首页 > 解决方案 > 如何在 Spring 集成测试中启动应用程序?

问题描述

我需要为我的应用程序创建一个集成测试。我使用@SpringBootTest(classes = {Application.class})注释来启动它,但它的启动需要时间。那么,当我的应用程序准备就绪时,我该如何运行测试呢?

问题出在kafka监听器中:

@SpringBootApplication
public class Application {

   @Autowired
   private KafkaConsumeHandler kafkaConsumeHandler;

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

   @KafkaListener(topics =  "${kafka.topics.test}",  containerFactory = "kafkaListenerContainerFactory")
public void listenRegistred(KafkaMessage consumeKafka) {
        kafkaConsumeHandler.handleStartProcess(consumeKafka);
}

如果我尝试在测试中立即发送消息,侦听器将无法捕获它们。所以我在发送前稍作停顿。

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class})
@DirtiesContext
public class ProcessTest {   

@ClassRule
public static KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, "testTopic");

@Test
public void sendTestRegistred() throws Exception {
    Thread.sleep(5000); // Need a delay to boot an application
    ...
}

标签: javaspring-bootjunit

解决方案


您需要添加带有注释的类@SpringBootApplication

例子:

@SpringBootApplication
public class SpringApp {}

@SpringBootTest(classes = SpringApp.class)
public class IntegrationTest {}

另外,请注意,集成测试总是比单元测试慢,您需要确定测试某个功能所需的测试类型。

有问题的更新后更新: 在您的情况下,测试的延迟是由于等待KafkaEmbded开始而引起的。因此,您必须找到一种以编程方式确定何时Kafka准备就绪的方法。这是应该起作用的一种可能性:

@Before
public void setUp() throws Exception {
   // wait until the partitions are assigned
   for (MessageListenerContainer messageListenerContainer : 
        kafkaListenerEndpointRegistry.getListenerContainers()) {

       ContainerTestUtils.waitForAssignment(messageListenerContainer,
       embeddedKafka.getPartitionsPerTopic());
   }

代码取自这里:https ://github.com/code-not-found/spring-kafka/blob/master/spring-kafka-avro/src/test/java/com/codenotfound/kafka/SpringKafkaApplicationTest.java# L42 如果这不起作用,请查看如何等待KafkaEmbedded启动。您的问题不是由 SpringBootTest 引起的。


推荐阅读