【问题标题】:Embedded Spring-Kafka makes unrelated unit tests fail嵌入式 Spring-Kafka 使无关的单元测试失败
【发布时间】:2023-03-10 15:31:01
【问题描述】:

内存服务器中的 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 包含到每个单元测试中)-;

如何避免如此严厉的措施?

【问题讨论】:

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


    【解决方案1】:

    每当您在测试类中使用@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”); }

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

    SpringJmsApplicationTest 的问题在于它完全基于@SpringBootTest,它将加载您的SpringApplication 以及嵌套包中的所有@Configuration 类,包括KafkaReceiverConfig 和@987654337 @。我假设您不希望在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 {
    

    【讨论】:

    • 不幸的是,我似乎无法让它像那样工作。请参阅回购:link
    • 在我的回答中查看更新。
    • 非常感谢您的热心帮助!现在可以工作了。 repo
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 2016-12-03
    • 2018-07-23
    • 2020-07-07
    • 2021-07-15
    • 1970-01-01
    相关资源
    最近更新 更多