9

I am building an application using RabbitMQ with Spring: so far so good. To define Unit Tests I am using JUnit targeting an external server. What I wanted to find out is if there is a way to mock the RabbitMQ server to perform tests, and if there is more than a way, which is the best one.

I found some posts around but they were made in 2012 or even before... maybe there's something newer, easier and more effective !

Thanks in advance

Ing. Luca Stucchi
  • 3,070
  • 6
  • 36
  • 58

4 Answers4

7

I wouldn't try to mock the RabbitMQ server itself; instead, mock your publication methods, channel factories, and so on in order to emulate error conditions (and the happy path, of course). What happens when your FoozleEvent.publish method throws an IOError, for example?

asthasr
  • 9,125
  • 1
  • 29
  • 43
3

We use mocking extensively for tests in the framework itself; explore the tests for ideas. It's not too bad on the RabbitTemplate side, but mocking for the listener container is more involved.

In some case, though, a real integration test is needed and in that case we use a JUnit @Rule to ignore the tests if there's not a local rabbitmq broker.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Thanks Gary, for the moment we decided to test only our internal service, cutting away the RabbitMQ integration, but thanks to your indication now I have a better understanding of how tests are performed ! Thanks ! – Ing. Luca Stucchi Jan 20 '15 at 09:14
  • Thanks for the tip, so you are saying you are testing on the sending side only, not on the RabbitListener side. In this case you setup integration tests with a real running rabbitMQ installation (wih Rule)? If you do use testing with RabbitListener is there any code doing it? And how can you make sure it's not consumed directly i.e. you want to check the message on the RabbitListener side with the test case i.e. can't be consumed before hand by the normal RabbitListener outside the testcase. – powder366 Mar 14 '17 at 08:05
  • 1
    You should really ask a new question. No, we do have mock tests on the consumer side too, but it is quite complex and requires some knowledge of the framework internals. As I said, explore the framework tests in the `listener` package. You can use a different virtual host and/or queue name when performing integration tests using the `@Rule` (which is now provided in the `spring-rabbit-junit` jar - since 1.7) [Documentation here](http://docs.spring.io/spring-amqp//reference/html/_reference.html#testing). – Gary Russell Mar 14 '17 at 12:58
1

To mock RabbitMQ in the Java world, there is a library that I am building : rabbitmq-mock.

The purpose is exactly the use case you describe. You can simply replace the amqp-client ConnectionFactory and you will have most of RabbitMQ features out of the box, without using IO (no port binding is needed) and without startup time.

Simply add the dependendy in your pom.xml:

<dependency>
    <groupId>com.github.fridujo</groupId>
    <artifactId>rabbitmq-mock</artifactId>
    <version>1.0.14</version>
    <scope>test</scope>
</dependency>

Then you can use it through a replacement of the ConnectionFactory you provided through Spring configuration or that Spring-Boot have provided for you:

@Configuration
@Import(AppConfiguration.class)
class TestConfiguration {
    @Bean
    ConnectionFactory connectionFactory() {
        return new CachingConnectionFactory(new MockConnectionFactory());
    }
}

Hope this will help !

Loïc Le Doyen
  • 975
  • 7
  • 16
1

Another approach, instead of mocking the RabbitMQ server itself, is to mock the dependent service on the other side of the external RabbitMQ server. You can do this using an async API simulation/mocking tool.

For example you can use Traffic Parrot which can be run in a Docker container as part of your CI/CD pipeline.

Here is a video demo of how you can use the tool to send mock response messages to a RabbitMQ queue in an aysnc request/response pattern. There is also a corresponding tutorial available to follow.

Request/Response RabbitMQ pattern Recording gRPC messages Replaying gRPC messages

Liam Williams
  • 676
  • 9
  • 16