先前的集成测试消耗了当前的测试队列消息

问题描述 投票:0回答:2

因此,我正在尝试在项目(rabbitmq)中使用一些队列。我决定创建简单的发布者/接收者集成测试。

所以我做了简单的发件人

@Component
public class QueueSender {
    ...
    public void sendMessage(@RequestParam String message) {
        rabbitTemplate.convertAndSend(queue, message);
    }
}

和相应的测试

@SpringBootTest(classes = QueueSender.class, webEnvironment = SpringBootTest.WebEnvironment.NONE)
@Import(RabbitAutoConfiguration.class)
class QueueSenderTest {
    ... --docker rabbitmq instance is one for all tests.
    @Test
    void shouldSendMessageToQueue() {
        String message = "hello world";

        queueSender.sendMessage(message);

        Object response = rabbitTemplate.receiveAndConvert(queue, MAX_TIMEOUT_MILLIS);
        assertEquals(message, response);
    }
}

和简单接收器

@Component
public class QueueListener {

    @RabbitListener(queuesToDeclare = @Queue("${queues.listener}"))
    public void listener(Message object) {
        System.out.println("received " + object);
    }

}

和相应的测试

@SpringBootTest(classes = QueueListener.class, webEnvironment = SpringBootTest.WebEnvironment.NONE)
@Import(RabbitAutoConfiguration.class)
class QueueListenerTest {
    ... --docker rabbitmq instance is one for all tests.
    @Test
    void shouldFireListenerOnNewMessageOnQueue() {
        String message = "hello world";
        ArgumentCaptor<Message> argument = ArgumentCaptor.forClass(Message.class);

        rabbitTemplate.convertAndSend(queue, message);

        verify(queueListener, timeout(MAX_TIMEOUT_MILLIS)).listener(argument.capture());
        assertEquals(message, new String(argument.getValue().getBody()));
    }
}

队列配置位于application.properties中

queues:
    listener: "listen-queue-name"
    sender: "sender-queue-name"

一切正常,直到我不会尝试对两个测试使用相同的队列并立即运行它们

queues:
    listener: "listen-queue-name"
    sender: "listen-queue-name"

在这种情况下,SenderTest总是失败。

因此,当我调试SenderTest时,由于调试器在QueueListener中停止,所以似乎以前的测试的Spring上下文会消耗消息,这甚至在QueueSender测试的上下文中也不会-.-

有趣的事实是,将那些测试类中的一个移动到另一个程序包解决了这个问题,因此probalby SenderTest被触发得如此之快,以至于先前测试中的RabbitListener仍然被注册。

DirtiesContext也可以,但是我不想使用它。有什么想法吗?

spring spring-boot rabbitmq junit5
2个回答
0
投票

从弹簧documentation

Spring的测试框架在测试之间缓存应用程序上下文。因此,只要您的测试共享相同的配置(否(无论如何发现),可能会耗时加载上下文仅发生一次。

这就是您的问题。


0
投票

不完全是您问题的答案,而是更多建议。您可以尝试使用用于RabbitMQ的测试容器。因此,基本上,您的测试用例将

1-启动RabbitMq测试容器,它将创建队列。

2--进行测试

3--破坏测试容器。

所有这些都应该很快。这将确保所有测试类都使用独立的队列,因此不会任何冲突的可能性。我认为这应该是一种更清洁的测试方法。

测试容器:https://www.testcontainers.org/modules/rabbitmq/

© www.soinside.com 2019 - 2024. All rights reserved.