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 类你有嵌套的包,包括 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 {