Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 208
Ayodeji Avatar asked Jan 03 '14 17:01

Ayodeji


1 Answers

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);
    // ...
like image 123
Andrea C Avatar answered Oct 18 '22 05:10

Andrea C