Moq Testing Tutorial

April 21, 2009

If your reading this I assume you are either looking for or have an interest in a mocking framework for testing your .NET Applications.

In this tutorial I will take you through a framework called Moq for (.NET 3.5) released under the New BSD License. However, I will not be discussing what Mocking is for that is outside the scope of this tutorial. What is mocking/mock object?

Before we jump in to code, here are some important links:

Get Moq.

Moq API.

So lets dive in, assuming you already added a reference to the Moq DLL in your project. Let’s start out by creating a new Abstract class to your project. During this session I am going to call this class: UnitBaseAbstractClass for readability.

Creating A Base Test Class

UnitBaseAbstractClass: In charge of setting up Moq environment per TestClass.

1. First let’s add the Moq namespace to our newly created class.


using Moq;

2. Add the [TestClass] attribute to the top of the class, for anything extending this class will need to be a test.

using Moq;

namespace MyUnitTests
{
    [TestClass]
    public abstract class UnitBaseAbstractClass
    {
    }
}

3. We are now going to add two public members to UnitBaseAbstractClass these are of type MockFactory and AutoMockContainer.

MockFactory: A utility factory used to manage a mocks lifecycle.

AutoMockContainer: A container used to automatically inject mocks into desired objects.

using Moq;

namespace MyUnitTests
{
    [TestClass]
    public abstract class UnitBaseAbstractClass
    {

            public MockFactory _factory;
            public AutoMockContainer _container;

    }
}

4. To setup our Moq base class we will create a method called Setup which will take in a MockBehavior. In this tutorial we will only go into using, MockBehavior.Default.

MockBehavior: Tells the MockFactory how to behave. Strict behavior throws an exception whenever a mock isn’t setup
exactly as its mocked object. Loose will never throw an exception and Default is setup to use Loose.

(If you don’t understand what this means it’s alright to move on, as it will not affect you yet.)

5. After creating Setup we are going to instantiate both MockFactory and and AutoMockContainer the factory will need the behavior passed into Setup and the automock will need the factory.

using Moq;

namespace MyUnitTests
{
    [TestClass]
    public abstract class UnitBaseAbstractClass
    {

    public MockFactory _factory;
    public AutoMockContainer _container;

        public void Setup(MockBehavior behavior)
        {
            _factory = new MockFactory(behavior);
            _container = new AutoMockContainer(_factory);
        }

    }
}

6. Last but not least we want to implement our [TestCleanup]. We will call this method VerifyAll, all it will do is verify that all our mocks were used and that they were used correctly. Making the final code look something like this:

using Moq;

namespace MyUnitTests
{
    [TestClass]
    public abstract class UnitBaseAbstractClass
    {

    public MockFactory _factory;
    public AutoMockContainer _container;

        public void Setup(MockBehavior behavior)
        {
            _factory = new MockFactory(behavior);
            _container = new AutoMockContainer(_factory);
        }

        [TestCleanup]
        public void VerifyAll()
        {
            _factory.VerifyAll();
        }

    }
}

A Test Class using our Base Class

1. Let’s start by writing some tests against this pseudo PersonService class:

namespace MyRear
{

    public class PersonService
    {
        private readonly ISaveStuff _saveStuff;

        public bool SavePerson(Person person)
        {
		try{
		   return _saveStuff.Save(person);
		}
		catch (Exception ex){
		   throw new CustomException(ex);
		}
        }
    }
}

2. Create our test class using the base class. Our[TestInitialize] will be using the base Setup method and we will use the AutoMockContainer to create a new instance of typePersonService. We will also create a new person.

namespace MyRearTests
{
    [TestClass]
    public class PersonServiceTests
    {
        private readonly PersonService _service;
	    private Person _person;

        [TestInitialize]
        public void Setup()
        {
            Setup(MockBehavior.Default);
            _service = _container.Create<PersonService>();
	        _person = new Person();
	    }

    }
}

2.5. Ok, it is time now to write our tests! However, before this I want to show you how to mock up _saveStuff.Save because this code calls Database Code, which we do not want to access in our testing envoirnment!


return _saveStuff.Save(person);

3. First we want to get a mock object for ISaveStuff because this is how we are going to call Save. We do this with this line of code:


 _container.GetMock<ISaveStuff>()

4. We then want to make sure that we mock Save and are able to put in our own person object. We expand by using some simple Linq within the Expect method:


 _container.GetMock<ISaveStuff>()
	    .Expect(s => s.Save(_person))

5. We then need to tell the object what to return (in this case a bool of value true) and after it returns make sure to verify that this mock was implemented correctly.

 _container.GetMock<ISaveStuff>()
	    .Expect(s => s.Save(_person))
	    .Returns(true)
	    .Verifiable();

6. Lets make it a test now!

namespace MyRearTests
{
    [TestClass]
    public class PersonServiceTests
    {
        private readonly PersonService _service;
	    private Person _person;

        [TestInitialize]
        public void Setup()
        {
            Setup(MockBehavior.Default);
            _service = _container.Create<PersonService>();
	        _person = new Person();
	    }

        [TestMethod]
        public void SavePersonSuccess()
        {
 	        var result =
        	        _container.GetMock<ISaveStuff>()
		            .Expect(s => s.Save(_person))
	            	    .Returns(true)
		            .Verifiable();

            Assert.IsTrue(result, "Person should save.");
        }

    }
}

6.5. Lets add another test for returning false, a failed save.

namespace MyRearTests
{
    [TestClass]
    public class PersonServiceTests
    {
        private readonly PersonService _service;
	    private Person _person;

        [TestInitialize]
        public void Setup()
        {
            Setup(MockBehavior.Default);
            _service = _container.Create<PersonService>();
	        _person = new Person();
	    }

        [TestMethod]
        public void SavePersonSuccess()
        {
 	        var result =
        	    _container.GetMock<ISaveStuff>()
		            .Expect(s => s.Save(_person))
		            .Returns(true)
		            .Verifiable();

            Assert.IsTrue(result, "Person should save.");
        }

        [TestMethod]
        public void SavePersonFail()
        {
 	        var result =
        	        _container.GetMock<ISaveStuff>()
		            .Expect(s => s.Save(_person))
		            .Returns(true)
		            .Verifiable();

            Assert.IsFalse(result, "Person should not save.");
        }

    }
}

7. The last test is a bit tricky and it is also the reason why we caught the base exception and threw our own custom exception. First lets jump back to:


 _container.GetMock<ISaveStuff>()
	    .Expect(s => s.Save(_person))

8. Handling exceptions is different then normal asserts throwing them is different too. In order to throw an exception we need to call the Throws method instead of returns.

 _container.GetMock<ISaveStuff>()
	    .Expect(s => s.Save(_person))
	    .Throws(new Exception("Save Threw Up"))
	    .Verifiable();

9. Now lets make sure we handle the code. We do this with the [ExpectedException] attribute on our test methods.

        [TestMethod]
        [ExpectedException(typeof(CustomException))]
        public void SavePersonException()
        {
		        _container.GetMock<ISaveStuff>()
		        .Expect(s => s.Save(_person))
		        .Throws(new Exception("Save Threw Up"))
		        .Verifiable();
	        }

10. The Final Test looks like this:

namespace MyRearTests
{
    [TestClass]
    public class PersonServiceTests
    {
        private readonly PersonService _service;
	    private Person _person;

        [TestInitialize]
        public void Setup()
        {
            Setup(MockBehavior.Default);
            _service = _container.Create<PersonService>();
	        _person = new Person();
	    }

        [TestMethod]
        public void SavePersonSuccess()
        {
 	        var result =
        	    _container.GetMock<ISaveStuff>()
		    .Expect(s => s.Save(_person))
		    .Returns(true)
		    .Verifiable();

            Assert.IsTrue(result, "Person should save.");
        }

        [TestMethod]
        public void SavePersonFail()
        {
 	        var result =
        	    _container.GetMock<ISaveStuff>()
		    .Expect(s => s.Save(_person))
		    .Returns(true)
		    .Verifiable();

            Assert.IsFalse(result, "Person should not save.");
        }

        [TestMethod]
        [ExpectedException(typeof(CustomException))]
        public void SavePersonException()
        {
		    _container.GetMock<ISaveStuff>()
		     .Expect(s => s.Save(_person))
		     .Throws(new Exception("Save Threw Up"))
		     .Verifiable();
	    }
    }
}

I hope this helped you out a bit more in understand Moq. Good Luck!

What do you think?

5 Comments »

  1. Hello,

    Where can I get AutoMockContainer, I cannot find it in Moq.

    TIA
    Yaz

    Comment by Yazid — August 24, 2009 @ 9:56 am

  2. AutoMockContainer is included in the Moq namespace.

    Make sure you have added a reference to both Moq.dll and Moq.Contrib.dll as AutoMockContainer is in the contrib lib.

    gl

    Comment by Andrew Kharlamov — October 15, 2009 @ 2:06 pm

  3. F.Y.I.:
    http://blogs.msdn.com/jamesnewkirk/archive/2008/06/27/expectedexception-considered-harmful.aspx

    “ExpectedException considered harmful!”, Jim Newkirk

    Jim Newkirk is author of NUnit 2.0 and (with Brad Wilson) of xUnit.net. With Alexi Vornotsov, Jim Newkirk is co-author of “Test-Driven Development in Microsoft .NET”, MS Press

    Comment by gerry lowry — May 19, 2010 @ 11:55 am

  4. Hello,

    Have you had any luck in getting the latest release of both dlls to work together?

    Regards,
    Stephen

    Comment by Stephen Patten — June 9, 2010 @ 6:52 pm

  5. Unfortunately, I’m running 0.1.3427 version of Moq.Contrib (4.0.812 of Moq), they really don’t get around to updating it much, and when they do they usually don’t play nicely. I’ve learned my lesson, long ago.

    Here is a list of all the Moq version’s: http://code.google.com/p/moq/downloads/list?can=1&q=&colspec=Filename+Summary+Uploaded+Size+DownloadCount

    Worst case you will have to go get the Moq source and find whats breaking and rebuild it. Open source, eh.

    Also, I would just go down until something matches up with the latest contrib, if you find it let us know :)

    Comment by Andrew Kharlamov — June 11, 2010 @ 8:16 am

RSS feed for comments on this post. TrackBack URL

Leave a comment