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

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

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

但是,由于我的 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,但如果可以的话,我希望测试整个系统。如果无法以相当干净的方式实现我的目标,我计划退回到该解决方案。

【问题讨论】:

    标签: spring-amqp


    【解决方案1】:

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

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

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

    另见integration test cases in the framework itself

    【讨论】:

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