Spring启动应用程序找不到占位符';spring.embedded.kafka.brokers';斯波克弹簧试验
我正在尝试使用Spring Boot、Spock Spring和嵌入式Kafka进行集成测试。接着,我发现“由于嵌入式代理是在随机端口上启动的,我们无法使用Spring启动应用程序找不到占位符';spring.embedded.kafka.brokers';斯波克弹簧试验,spring,spring-kafka,Spring,Spring Kafka,我正在尝试使用Spring Boot、Spock Spring和嵌入式Kafka进行集成测试。接着,我发现“由于嵌入式代理是在随机端口上启动的,我们无法使用src/main/resources/application.yml属性文件中的固定值。幸运的是@ClassRule将spring.embedded.kafka.brokers系统属性设置为嵌入式代理的地址。” @ContextConfiguration @SpringBootTest(classes = [Application], web
src/main/resources/application.yml
属性文件中的固定值。幸运的是@ClassRule
将spring.embedded.kafka.brokers
系统属性设置为嵌入式代理的地址。”
@ContextConfiguration
@SpringBootTest(classes = [Application], webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext
@Stepwise
@ActiveProfiles("test")
class AnIntegrationTest extends Specification {
@Autowired
private KafkaListenerEndpointRegistry kafkaListenerEndpointRegistry
@ClassRule
public static KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, "topic")
private KafkaTemplate<String, String> template
def setup() {
Map<String, Object> senderProperties = KafkaTestUtils.senderProps(embeddedKafka.getBrokersAsString())
ProducerFactory<String, String> producerFactory =
new DefaultKafkaProducerFactory<String, String>(senderProperties)
template = new KafkaTemplate<>(producerFactory)
template.setDefaultTopic("topic")
for (MessageListenerContainer messageListenerContainer : kafkaListenerEndpointRegistry
.getListenerContainers()) {
ContainerTestUtils.waitForAssignment(messageListenerContainer, embeddedKafka.getPartitionsPerTopic())
}
}
def "test"() {
given:
template.sendDefault("Hello")
}
}
在应用程序中,我使用spring Kafka
启动一个Kafka消费者。
堆栈跟踪是
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener.prepareTestInstance(SpringBootDependencyInjectionTestExecutionListener.java:44)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230)
at org.spockframework.spring.SpringTestContextManager.prepareTestInstance(SpringTestContextManager.java:50)
at org.spockframework.spring.SpringInterceptor.interceptSetupMethod(SpringInterceptor.java:42)
at org.spockframework.runtime.extension.AbstractMethodInterceptor.intercept(AbstractMethodInterceptor.java:28)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:88)
at org.spockframework.runtime.extension.builtin.AbstractRuleInterceptor$1.evaluate(AbstractRuleInterceptor.java:37)
at org.togglz.junit.TogglzRule$1.evaluate(TogglzRule.java:127)
at org.spockframework.runtime.extension.builtin.TestRuleInterceptor.intercept(TestRuleInterceptor.java:38)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'kafkaListenerContainerFactoryConfiguration': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.embedded.kafka.brokers' in value "${spring.embedded.kafka.brokers}"
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:372)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:120)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116)
... 19 more
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.embedded.kafka.brokers' in value "${spring.embedded.kafka.brokers}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)
at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:236)
at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210)
at org.springframework.core.env.AbstractPropertyResolver.resolveNestedPlaceholders(AbstractPropertyResolver.java:227)
at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:84)
at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:61)
at org.springframework.core.env.AbstractEnvironment.getProperty(AbstractEnvironment.java:527)
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer$1.getProperty(PropertySourcesPlaceholderConfigurer.java:132)
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer$1.getProperty(PropertySourcesPlaceholderConfigurer.java:129)
at org.springframework.core.env.PropertySourcesPropertyResolver.getProperty(PropertySourcesPropertyResolver.java:81)
at org.springframework.core.env.PropertySourcesPropertyResolver.getPropertyAsRawString(PropertySourcesPropertyResolver.java:71)
at org.springframework.core.env.AbstractPropertyResolver$1.resolvePlaceholder(AbstractPropertyResolver.java:239)
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:147)
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)
at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:236)
at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210)
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer$2.resolveStringValue(PropertySourcesPlaceholderConfigurer.java:172)
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:831)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1086)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366)
... 36 more
有人有线索吗?我不熟悉Spock,但一个简单的Java JUnit测试很好用
@SpringBootApplication
public class So47172973Application {
public static void main(String[] args) {
SpringApplication.run(So47172973Application.class, args);
}
@KafkaListener(topics = "foo")
public void in(String in) {
System.out.println(in);
}
}
及
及
我在
setup()
中调用了embeddedKafka.before()
。然后,spring.embedded.kafka.brokers
被设置并可用
我不确定,但问题似乎与斯波克·斯普林有关。也有类似的问题,@taro的回答没有解决我的问题 我通过从
嵌入的Kafka
对象中删除
,并用@Rule
注释替换@ClassRule
解决了这个问题
@Rule
public KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, "topic")
确保在每个集成测试中都设置了
@SpringBootTest
和@EmbeddedKafka
当您使用@SpringBootTest
注释同时运行多个集成测试时,这是常见的错误。由于您已经在应用程序配置器bean中注册了DefaultKafkanConsumerFactory
和DefaultKafkaProducerFactory
,并且可能还使用了@Value(${spring.kafka.bootstrap servers}”)
,因此您有义务设置@EmbeddedKafka(分区=1,主题={“topic”})
调用spring启动应用程序在测试服务器容器上运行的任何地方@EmbeddedKafka
负责调用EmbeddedKafka文本定制器
,以注册kafka引擎所需的所有环境变量(包括spring.embedded.kafka.brokers
)
如果集成测试中没有
@EmbeddedKafka
,spring将在服务器上运行应用程序,但没有设置kafka引擎使用的环境的机制。啊,有人知道吗?看起来它需要的是实际值,而不是嵌入式kafka,因此,我使用不同的配置文件进行不同的测试around@MohammedRafeeq你能详细说明你做了什么吗?
spring:
kafka:
bootstrap-servers:
- ${spring.embedded.kafka.brokers}
consumer:
group-id: embedded1
auto-offset-reset: earliest
@RunWith(SpringRunner.class)
@SpringBootTest
public class So47172973ApplicationTests {
@ClassRule
public static KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, "foo");
@Autowired
private KafkaTemplate<String, String> template;
@Test
public void test() throws InterruptedException {
template.send("foo", "bar");
Thread.sleep(10_000);
}
}
@RunWith(SpringRunner.class)
@SpringBootTest
@EmbeddedKafka(controlledShutdown = true, topics = "foo")
public class So47172973ApplicationTests {
@Autowired
private KafkaTemplate<String, String> template;
@Test
public void test() throws InterruptedException {
template.send("foo", "bar");
Thread.sleep(10_000);
}
}
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {So47172973ApplicationTests.Config.class, So47172973Application.class})
public class So47172973ApplicationTests {
@Autowired
private KafkaTemplate<String, String> template;
@Test
public void test() throws InterruptedException {
template.send("foo", "bar");
Thread.sleep(10_000);
}
@Configuration
public static class Config {
@Bean
public KafkaEmbedded embeddedKafka() {
return new KafkaEmbedded(1, true, "foo");
}
}
}
@Rule
public KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, "topic")