嵌入式Spring-Kafka使无关的单元测试失败

时间:2019-03-18 20:11:04

标签: java spring-boot junit apache-kafka spring-kafka

内存服务器中的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配置类:

@Configuration
@EnableKafka
public class KafkaReceiverConfig {

  @Value("${kafka.bootstrap-servers}")
  private String bootstrapServers;

  @Bean
  public KafkaReceiver kafkaReceiver() {
     return new KafkaReceiver();
  }
}

灵感来自here

目前的解决方法是将嵌入式Kafka包含在每个单元测试中)-;

如何避免这种严厉措施?

1 个答案:

答案 0 :(得分:3)

每当在测试类中使用@EmbeddedKafka时,您都可以这样做:

static {
    System.setProperty(EmbeddedKafkaBroker.BROKER_LIST_PROPERTY,
            "spring.kafka.bootstrap-servers");
}

因此,这种方式EmbeddedKafkaBroker将通过随机端口将其地址公开到spring.kafka.bootstrap-servers中。因此,您不需要在application.yml中进行更改,并且在其他类中也不需要@EmbeddedKafka

更新

好!看起来您不依赖于Spring Boot自动配置及其常规属性。

因此,要使SpringKafkaApplicationTest工作,您需要具有以下系统属性:

静态{     System.setProperty(EmbeddedKafkaBroker.BROKER_LIST_PROPERTY,             “ kafka.bootstrap-servers”);   }

您根本不需要在kafka.bootstrap-servers中拥有该application.yml属性。

SpringJmsApplicationTest的问题完全基于@SpringBootTest,而该问题将为您的SpringApplication加载嵌套软件包中的所有@Configuration类,包括KafkaReceiverConfigKafkaSenderConfig。我假设您不希望使用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 {