在春季启动的Junit在@EmbeddedKafka推后获得来自主题数据

时间:2019-01-31 03:30:02

标签: spring-boot spring-kafka embedded-kafka spring-kafka-test

我写的JUnit测试用例(使用@EmbeddedKafka)为我的春节,启动应用程序,它广泛使用Spring的卡夫卡与其他服务和其他业务交流。

一种典型的情况是从kafka中删除数据(我们通过在kafka中推送 null 消息来完成此操作)。

当前,在delete()方法中,我们通过首先检查kafka中是否存在任何需要删除的消息来进行此操作。 然后,我们推的作为在该卡夫卡消息密钥

为上述方法逻辑编写Junit的步骤如下。

@Test
public void test(){
   //Push a message to Kafka (id=1234)
   //call test method service.delete(1234);
       //internally service.delete(1234) checks/validate whether message exists in kafka and then push null to delete topic.
  //check delete topic for delete message received.
  // Assertions
}

这里的问题是Kafka总是抛出未找到消息的异常。内部service.delete()方法。

在控制台中检查日志时。我发现我的生产者配置使用不同的kafka端口,而消费者配置使用不同的端口。

我不知道是否我已经错过了一些微小的细节或什么是这种现象的原因。 任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我有一个简单的Spring Boot应用供您考虑:

@SpringBootApplication
public class SpringBootEmbeddedKafkaApplication {

    public static final String MY_TOPIC = "myTopic";

    public BlockingQueue<String> kafkaMessages = new LinkedBlockingQueue<>();

    public static void main(String[] args) {
        SpringApplication.run(SpringBootEmbeddedKafkaApplication.class, args);
    }

    @KafkaListener(topics = MY_TOPIC)
    public void listener(String payload) {
        this.kafkaMessages.add(payload);
    }

}

application.properties

spring.kafka.consumer.group-id=myGroup
spring.kafka.consumer.auto-offset-reset=earliest

并测试:

@RunWith(SpringRunner.class)
@SpringBootTest(properties =
        "spring.kafka.bootstrapServers:${" + EmbeddedKafkaBroker.SPRING_EMBEDDED_KAFKA_BROKERS + "}")
@EmbeddedKafka(topics = SpringBootEmbeddedKafkaApplication.MY_TOPIC)
public class SpringBootEmbeddedKafkaApplicationTests {

    @Autowired
    private KafkaTemplate<Object, String> kafkaTemplate;

    @Autowired
    private SpringBootEmbeddedKafkaApplication kafkaApplication;

    @Test
    public void testListenerWithEmbeddedKafka() throws InterruptedException {
        String testMessage = "foo";
        this.kafkaTemplate.send(SpringBootEmbeddedKafkaApplication.MY_TOPIC, testMessage);

        assertThat(this.kafkaApplication.kafkaMessages.poll(10, TimeUnit.SECONDS)).isEqualTo(testMessage);
    }

}

请注意spring.kafka.consumer.auto-offset-reset=earliest,以使使用者可以从分区的开头进行读取。

要在测试中应用的另一个重要选项是:

@SpringBootTest(properties =
        "spring.kafka.bootstrapServers:${" + EmbeddedKafkaBroker.SPRING_EMBEDDED_KAFKA_BROKERS + "}")

@EmbeddedKafka填充一个spring.embedded.kafka.brokers系统属性,并进行Spring Boot自动配置,以了解我们需要将其值复制到spring.kafka.bootstrapServers配置属性中。

或者根据我们的docs

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