Ayodeji
Ayodeji

Reputation: 579

Unit test on rabbitMQ

I have an application that publishes event to RabbitMQ and a consumer which consumes the event. My question is is there a way to write a unit test to test the functionality of this consumer.

Just to add this, the consumer works more in an hierarchical structure i.e, if an order event is posted, the suborders in it are extracted and posts their corresponding events to a queue when the suborders get consumed the lineItems in each one is also posted to a queue and lastly the details for each lineItem would be posted to.

Upvotes: 10

Views: 19403

Answers (2)

Andrea C
Andrea C

Reputation: 329

Extending on the previous answer, here's a very quick implementation for the unit test route (using Mockito). The starting point is one of RabbitMQ's own tutorials for java.

Receiver class (message handler)

public class LocalConsumer extends DefaultConsumer {

    private Channel channel;
    private Logger log;

    // manual dependency injection
    public LocalConsumer(Channel channel, Logger logger) {
        super(channel);
        this.log = logger;
    }

    @Override
    public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
            throws IOException {
        String message = new String(body, "UTF-8");
        // insert here whatever logic is needed, using whatever service you injected - in this case it is a simple logger.
        log.print(" [x] Received and processed '" + message + "'");
    }
}

Test class

public class LocalConsumerTest {

    Logger mockLogger = mock(Logger.class);
    Channel mockChannel = mock(Channel.class);
    String mockConsumerTag = "mockConsumerTag";

    LocalConsumer _sut = new LocalConsumer(mockChannel, mockLogger);

    @Test
    public void shouldPrintOutTheMessage () throws java.io.IOException {
        // arrange
        String message = "Test";
        // act
        _sut.handleDelivery(mockConsumerTag, null, new AMQP.BasicProperties(), message.getBytes() );
        // assert
        String expected = " [x] Received and processed '" + message + "'";
        verify(mockLogger).print(eq(expected));
    }
}

Consumer

    // ...
    // this is where you inject the system you'll mock in the tests.
    Consumer consumer = new LocalConsumer(channel, _log);
    boolean autoAck = false;
    channel.basicConsume(queueName, autoAck, consumer);
    // ...

Upvotes: 1

Younes
Younes

Reputation: 1671

It looks like the way to have an easy-to-use solution for testing RabbitMQ-related develoment is still far to reach.

See this discussion and this discussion from SpringFramework forum. They are either using Mockito (for unit-tests) or a real RabbitMQ instance (integration tests) for their own testing.

Also, see this post where the author uses an real RabbitMQ byt with some facilities to make that more 'test-friendly' task. However, as of now, the solution is valid only for MAC users!

Upvotes: 3

Related Questions