Carl Hörberg on development

RabbitMQ is a very good open source message queue server, but unfortunately it's DotNet API isn't very "dotnetish". Well, finally I figured out a way to unit test classes which relied upon IModel.

[TestFixture]
public class RabbitMQTest
{
[Test]
    public void CanMockMQ()
    {
        // Arrange
        var channelMock = new Mock<IModel>();
        channelMock
            .Setup(m => m.BasicConsume(It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<IDictionary>(), It.IsAny<IBasicConsumer>()))
            .Callback<string, bool, object, IBasicConsumer>((queue, noAck, props, consumer) => consumer.HandleBasicDeliver("", 1, false, "exchange", "route", null, new byte[0]));
        var server = new MQUser(channelMock.Object);

        // Act
        server.Abort();
        server.DoStuff();

        // Assert
        channelMock.Verify(m => m.BasicAck(1, false));
    }
}
view raw Test.cs This Gist brought to you by GitHub.
public class MQUser
{
    readonly IModel channel;

    public MQUser(IModel channel)
    {
        this.channel = channel;
    }

    public void DoStuff()
    {
        var queueName = channel.QueueDeclare();
        var subscription = new Subscription(channel, queueName);
        do
        {
            var msg = subscription.Next();
            // Do stuff with the message
            subscription.Ack(msg);
        } while (!aborted);
    }

    bool aborted;
    public void Abort()
    {
        aborted = true;
    }
}

It uses Moq which let us mock the IModel interface and intercepts all calls to IModel#BasicConsume, which all subscribers must call to subscribe for messages, and then imeditly call IModel#HandleBasicDeliver which propagetes that a messages has arrived to the subscriber. Then the test continues by starting the class under test which contains a simple subscriber in a abortable loop. We will abort it before starting the loop (but becasue it's a do-while loop, it will try to fetch one message before returning). At last we verify that the message has been acknowledged.

 
blog comments powered by Disqus