RabbitMQ 集成测试和线程

Posted

技术标签:

【中文标题】RabbitMQ 集成测试和线程【英文标题】:RabbitMQ Integration Test and Threading 【发布时间】:2015-03-21 20:35:24 【问题描述】:

我通过实现 MessageListener 接口并设置 SimpleMessageListenerContainer 编写了一个 RabbitMQ 消费者。当我手动测试它时它运行良好。现在我想编写一个集成测试:

    创建消息 将消息推送到我的 RabbitMQ 服务器 等待消息被我的 MessageListener 实现使用 测试完成后会做出一些断言

但是,由于我的 MessageListener 在单独的线程中运行,这使得单元测试变得困难。在我的测试中使用 Thread.sleep 来等待 MessageListener 是不可靠的,我需要某种阻塞方法。

设置响应队列并使用rabbitTemplate.convertSendAndReceive 是我唯一的选择吗?我想避免设置响应队列,因为它们不会在实际系统中使用。

有没有办法只使用rabbitTemplate.convertAndSend 来完成此操作,然后以某种方式等待我的 MessageListener 接收消息并处理它?理想情况下,我会想象这样的事情:

rabbitTemplate.convertAndSend("routing.key", testObject);
waitForListner() // Somehow wait for my MessageListener consume the message
assertTrue(...)
assertTrue(...)

我知道我可以直接将消息传递给我的 MessageListener 而不连接到 RabbitMQ,但如果可以的话,我希望测试整个系统。如果无法以相当干净的方式实现我的目标,我计划退回到该解决方案。

【问题讨论】:

【参考方案1】:

有几种方法,最简单的方法是包装你的监听器并传入一个CountDownLatch,它由监听器和主测试线程使用倒计时

assertTrue(latch.await(TimeUnit.SECONDS));

您还可以将收到的实际消息传回,以便验证它是否符合预期。

另见integration test cases in the framework itself。

【讨论】:

这种方法对我来说效果很好,而且非常不引人注目。这篇文章***.com/questions/17827022/… 中的一些解释也很有帮助。 @GaryRussell 如果您有一个现有的 Listener 类,并且您希望避免添加 CountDownLatch 仅用于测试,该怎么办?在这种情况下是否有集成测试的解决方法? 你可以在监听容器中添加一个通知;见the discussion in this question/answer 和test case I added to the framework。这些以@RabbitListener 为中心,但同样的技术也适用。我有一些work in process here 来正式制定一种机制,为测试用例场景添加此类建议。 还有see this answer。但是,正如我在上面的答案中所说,您可以简单地包装您的侦听器并将锁存器放入包装器中,而无需更改您的侦听器对象。 我不了解框架本身的集成测试用例,而且SingleConnectionFactory目前甚至不可用,是我做错了什么吗?还是集成测试不适合在框架外使用?

以上是关于RabbitMQ 集成测试和线程的主要内容,如果未能解决你的问题,请参考以下文章

php RabbitMQ集成测试

使用远程Docker进行集成测试

集成测试和系统测试

RabbitMQ——SpringBoot集成RabbitMQ

RabbitMQ——SpringBoot集成RabbitMQ

集成测试概述