因此,我正在尝试在项目(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也可以,但是我不想使用它。有什么想法吗?
不完全是您问题的答案,而是更多建议。您可以尝试使用用于RabbitMQ的测试容器。因此,基本上,您的测试用例将
1-启动RabbitMq测试容器,它将创建队列。
2--进行测试
3--破坏测试容器。
所有这些都应该很快。这将确保所有测试类都使用独立的队列,因此不会任何冲突的可能性。我认为这应该是一种更清洁的测试方法。