RabbitMQ Integration Test and Threading

2020-03-17 04:55发布

问题:

I have written a RabbitMQ consumer by implementing the MessageListener interface and setting up a SimpleMessageListenerContainer. Its working well when I test it manually. Now I would like to write an integration test that:

  1. Creates a message
  2. Pushes the message to my RabbitMQ server
  3. Waits while the message is consumed by my MessageListener implementation
  4. Test makes some asserts once everything is done

However, since my MessageListener is running in a separate thread, it makes unit testing difficult. Using a Thread.sleep in my test to wait for the MessageListener is unreliable, I need some kind of blocking approach.

Is setting up a response queue and using rabbitTemplate.convertSendAndReceive my only option? I wanted to avoid setting up response queues, since they won't be used in the real system.

Is there any way to accomplish this using only rabbitTemplate.convertAndSend and then somehow waiting for my MessageListener to receive the message and process it? Ideally, I would imagine something like this:

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

I know I could just pass a message directly to my MessageListener without connecting to RabbitMQ at all, but I was hoping to test the whole system if it is possible to do so. I plan on falling back to that solution if there is no way to accomlish my goal in a reasonably clean way.

回答1:

There are several approaches, the easiest being to wrap your listener and pass in a CountDownLatch which is counted down by the listener and the main test thread uses

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

You can also pass back the actual message received so you can verify it is as expected.

Also see the integration test cases in the framework itself.



标签: spring-amqp