16

I want to Unit Test my application which use MSMQ but i found no way in order to Mock MessageQueue objects.

        var queuePath = @".\Private$\MyQueue";
        MessageQueue queue = null;
        if (MessageQueue.Exists(queuePath))
        {
            queue = new MessageQueue(queuePath);
        }
        else
        {
            queue = MessageQueue.Create(queuePath);
        }

I'm using Moq with xUnit.

Yoann. B
  • 11,075
  • 19
  • 69
  • 111

1 Answers1

30

So the basic problem here is that you have a hard dependency on the MessageQueue object. Generally when I have a situation like this, I'll create an interface, like IQueue and then create an implementation of IQueue for MessageQueue.

Then you can inject the IQueue dependency with Moq and test that your class is functioning as expected.

Something like this:

public interface IQueue
{
     bool Exists(string path);
     MessageQueue Create(string path);
}

The implementation would be something like this:

public MessageQueueImplementation : IQueue
{
    public bool Exists(string path)
    {
         return MessageQueue.Exists(path);
    }

    public MessageQueue Create(string path)
    {
         return MessageQueue.Create(path);
    }
}

Then for your class that depends on the MessageQueue something like this:

public class DependentOnQueue
{
    private IQueue queue;
    //inject dependency
    public DependentOnQueue(IQueue queue)
    {
        this.queue = queue;
    }

    public MessageQueue CreateQueue(string path)
    {
         //implement method that you want to test here
    }
}

Now you can inject an IQueue object using moq into this class that depends on the MessageQueue object and test the functionality.

lomaxx
  • 113,627
  • 57
  • 144
  • 179
  • 2
    word, All of my .NET projects seem to end up with these interface/wrappers for all of Microsoft's sealed classes (FileInfo, HttpContext, etc etc) – ryber Oct 26 '09 at 22:25
  • 3
    +1. This is also the accepted answer on the last 10 "How do I mock [Class X]?" questions. I'm not sure why people aren't picking up on this. – Anderson Imes Oct 26 '09 at 22:36
  • 4
    A wrapper class seems to work ok as a solution except for the `Create` method (which is supposed to be static by the way), because the signature for that method returns a `System.Messaging.MessageQueue`, which doesn't implement `IQueue`. Has anyone come up with a workaround for that? –  Dec 21 '11 at 16:50
  • @Cupcake You can create an IQueueManager or something similar, with a Create method that returns IQueue. Use an MsmqManager implementation of IQueueManager that in turn calls the static MessageQueue.Create and returns a MessageQueueImplementation of result. – Cristian Toma Jan 07 '16 at 13:05