Embedded Spring-Kafka使不相关的单元测试失败
Embedded Spring-Kafka makes unrelated unit tests fail
Spring-内存服务器中的Kafka是用随机端口启动的。因此 application.yml 条目是一个变量:
bootstrap-servers: ${spring.embedded.kafka.brokers}
但是这个属性只有在嵌入式Kafka服务器实际是运行的时候才会设置。
在没有嵌入式 Kafka 的单元测试中抛出异常(因为变量实际上没有被设置):
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'kafkaReceiverConfig': 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}"
这里是 Java 配置 class:
@Configuration
@EnableKafka
public class KafkaReceiverConfig {
@Value("${kafka.bootstrap-servers}")
private String bootstrapServers;
@Bean
public KafkaReceiver kafkaReceiver() {
return new KafkaReceiver();
}
}
灵感来自here。
目前的解决方法是将嵌入式 Kafka 包含到每个单元测试中)-;
如何避免采取如此严厉的措施?
每当你在测试 类 中使用 @EmbeddedKafka
时,你可以这样做:
static {
System.setProperty(EmbeddedKafkaBroker.BROKER_LIST_PROPERTY,
"spring.kafka.bootstrap-servers");
}
因此,这样 EmbeddedKafkaBroker
将通过随机端口将其地址直接公开到 spring.kafka.bootstrap-servers
。因此,您不需要 application.yml
中的更改,也不需要其他 类.
中的 @EmbeddedKafka
更新
好的!看起来您并不依赖 Spring 引导自动配置及其常规属性。
因此,要使 SpringKafkaApplicationTest
正常工作,您需要这样的系统 属性:
静态{
System.setProperty(EmbeddedKafkaBroker.BROKER_LIST_PROPERTY,
"kafka.bootstrap-servers");
}
您根本不需要在 application.yml
中包含 kafka.bootstrap-servers
属性。
SpringJmsApplicationTest
的问题是它完全基于 @SpringBootTest
,它将加载你的 SpringApplication
和所有 @Configuration
类你有嵌套的包,包括 KafkaReceiverConfig
和 KafkaSenderConfig
。我假设您不想在 SpringJmsApplicationTest
的情况下使用它们。因此,您应该考虑不要从 @SpringBootTest
.
加载整个应用程序
我看到的唯一一个快速解决方案是这样的:
@SpringBootTest(classes = { ActiveMqReceiverConfig.class, ActiveMqSenderConfig.class })
public class SpringJmsApplicationTest {
我猜你也可以对 SpringKafkaApplicationTest
做同样的事情:
@SpringBootTest(classes = { KafkaReceiverConfig.class, KafkaSenderConfig.class })
@DirtiesContext
@EmbeddedKafka(partitions = 1,
topics = { SpringKafkaApplicationTest.HELLOWORLD_TOPIC })
public class SpringKafkaApplicationTest {
Spring-内存服务器中的Kafka是用随机端口启动的。因此 application.yml 条目是一个变量:
bootstrap-servers: ${spring.embedded.kafka.brokers}
但是这个属性只有在嵌入式Kafka服务器实际是运行的时候才会设置。 在没有嵌入式 Kafka 的单元测试中抛出异常(因为变量实际上没有被设置):
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'kafkaReceiverConfig': 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}"
这里是 Java 配置 class:
@Configuration
@EnableKafka
public class KafkaReceiverConfig {
@Value("${kafka.bootstrap-servers}")
private String bootstrapServers;
@Bean
public KafkaReceiver kafkaReceiver() {
return new KafkaReceiver();
}
}
灵感来自here。
目前的解决方法是将嵌入式 Kafka 包含到每个单元测试中)-;
如何避免采取如此严厉的措施?
每当你在测试 类 中使用 @EmbeddedKafka
时,你可以这样做:
static {
System.setProperty(EmbeddedKafkaBroker.BROKER_LIST_PROPERTY,
"spring.kafka.bootstrap-servers");
}
因此,这样 EmbeddedKafkaBroker
将通过随机端口将其地址直接公开到 spring.kafka.bootstrap-servers
。因此,您不需要 application.yml
中的更改,也不需要其他 类.
@EmbeddedKafka
更新
好的!看起来您并不依赖 Spring 引导自动配置及其常规属性。
因此,要使 SpringKafkaApplicationTest
正常工作,您需要这样的系统 属性:
静态{ System.setProperty(EmbeddedKafkaBroker.BROKER_LIST_PROPERTY, "kafka.bootstrap-servers"); }
您根本不需要在 application.yml
中包含 kafka.bootstrap-servers
属性。
SpringJmsApplicationTest
的问题是它完全基于 @SpringBootTest
,它将加载你的 SpringApplication
和所有 @Configuration
类你有嵌套的包,包括 KafkaReceiverConfig
和 KafkaSenderConfig
。我假设您不想在 SpringJmsApplicationTest
的情况下使用它们。因此,您应该考虑不要从 @SpringBootTest
.
我看到的唯一一个快速解决方案是这样的:
@SpringBootTest(classes = { ActiveMqReceiverConfig.class, ActiveMqSenderConfig.class })
public class SpringJmsApplicationTest {
我猜你也可以对 SpringKafkaApplicationTest
做同样的事情:
@SpringBootTest(classes = { KafkaReceiverConfig.class, KafkaSenderConfig.class })
@DirtiesContext
@EmbeddedKafka(partitions = 1,
topics = { SpringKafkaApplicationTest.HELLOWORLD_TOPIC })
public class SpringKafkaApplicationTest {