Moq Testing Tutorial

Posted On: December 1st, 2009

If your reading this then 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 step you through a framework called Moq for (.NET) released under the New BSD License. I will not be discussing what Mocking is here as that’s outside the scope of this tutorial. What is mocking/mock object?

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

Get Moq.

Get Moq Contrib

Moq API.

So lets dive in, assuming you already added a reference to the Moq DLL and Moq.Contrib 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: This class is in charge of setting up a Moq based environment for each of your TestClass’.

1. First let’s add the Moq and Moq.Contrib namespaces to this UnitBaseAbstractClass class.


using Moq;
using Moq.Contrib;

That was simple!

2. Now lets add the [TestClass] attribute to the top of this class, for anything extending it will now need to be a test.

using Moq;
using Moq.Contrib;

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

3. This maybe a bit confusing but bare with me; we are now going to add two public members to our UnitBaseAbstractClass class these are of type MockFactory and AutoMockContainer. See the next example:

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

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

using Moq;
using Moq.Contrib;

namespace MyUnitTests
{
    [TestClass]
    public abstract class UnitBaseAbstractClass
    {

            public MockFactory _factory;
            public AutoMockContainer _container;

    }
}

tada…

4. We will now need to create a method called “Setup” which will take in a MockBehavior enum. In this tutorial we will only use: MockBehavior.Default.

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

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

5. We are going to use Setup to instantiate both MockFactory and AutoMockContainer the factory will need the behavior passed into Setup and the AutoMockContainer will need the MockFactory.

Like this:

using Moq;
using Moq.Contrib;

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 of our mocks were used and that they were used correctly. Making the final code look something like this:

using Moq;
using Moq.Contrib;

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();
        }

    }
}

Nice, small, and powerful.

A Test Class using our Base Class

The fun part!

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

namespace MyRear
{

    public class PersonService
    {
        private readonly IRepository _repository;

        public PersonService(IRepository repository)
        {
              _repository = repository;
        }
        public bool SavePerson(Person person)
        {
        		try{
        		   return _repository.Save(person);
        		}
	        	catch (Exception ex){
	        	   throw new CustomException(ex);
	        	}
        }
    }
}

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

That was a mouthful, like this:

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

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

    }
}

3. Time to write the tests! Before that though, I want to show you how to mock _repository.Save the code that calls the Database. Which in this case we do not want to access in our testing environment.

This code:


return _repository.Save(person);

4. First we want to get a mock object for IRepository because this is how we are going to call Save.

We do this with this line of code:


 _container.GetMock<IRepository>()

6. We then want to make sure that we can mock Save. We accomplish this via some Linq we call the Expect method.

In it we call Save and pass our _person object.


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

7. We then need to tell the object what to return (in this case I return a bool, lets say true). After calling the Returns method make sure to verify that this mock was even needed via Verifiable method.

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

8. Lets make it a test now!

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

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

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

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

    }
}

9. Lets add another test that returns false, a failed save.

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

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

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

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

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

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

    }
}

10. The last test is a bit tricky its why we wrapped Save in PersonService with a try catch and threw a custom exception.

First lets write something like this:


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

11. 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<IRepository>()
	    .Expect(s => s.Save(_person))
	    .Throws(new Exception("Save Threw Up"))
	    .Verifiable();

12. Lets make sure we handle the code. We do this with the [ExpectedException] attribute on our test methods.

Like so:

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

13. The Final Test looks like this:

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

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

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

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

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

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

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

I hope this helped you out a bit more in understanding the Moq Framework. Good Luck, let me know if I need to change anything in the tutorial or make anything clearer!

, , , , , ,

15 Comments »

  1. Hello,

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

    TIA
    Yaz

    Yazid (August 24th, 2009)

  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

    Andrew Kharlamov (October 15th, 2009)

  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

    gerry lowry (May 19th, 2010)

  4. Hello,

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

    Regards,
    Stephen

    Stephen Patten (June 9th, 2010)

  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 :)

    Andrew Kharlamov (June 11th, 2010)

  6. Thanks for the help, made my Friday night a whole lot faster. Moq is actually pretty neat, after you get it.

    John Snow (August 27th, 2010)

  7. [...] I will step you through a framework called Moq for (.NET) released under the New BSD License. I… [full post] Andrew Kharlamov CowFarm.NET development.netc#mock objects 0 0 0 [...]

    Moq Testing Tutorial (December 9th, 2010)

  8. I can’t reference Moq.contrib. I’m using the latests versions..please help!

    Kim Olsen (January 27th, 2011)

  9. @kim, I am going to need a little bit more information, Moq.Contrib is not apart of moq, so make sure to download it from: http://code.google.com/p/moq-contrib/downloads/list then add the reference to your project.

    Andrew Kharlamov (January 29th, 2011)

  10. I downloaded both moq and moq.contrib ( newest version ) and added them as references in my project. I can’t add the moq.contrib in the namespace though..pretty wierd!

    Kim Olsen (February 2nd, 2011)

  11. @kim, looks like your not the only one running into this issue, have a read through this and see if this solves your problems:

    http://code.google.com/p/moq-contrib/issues/detail?id=4

    Andrew Kharlamov (February 15th, 2011)

  12. Why use moc.contrib library? is it really necessare here?

    Zakhar (July 13th, 2011)

  13. Ah, sorry about moc.contrib question, found the answer in one of the comments

    Zakhar (July 13th, 2011)

  14. The type or namespace name ‘Contrib’ does not exist in the namespace ‘Moq’
    Neither Moc.dll, nor Moc.Contrib contain ‘Moq.Contrib’ namespace.
    Is this post still alive? Can the author please check and update it? Thanks

    Zakhar (July 13th, 2011)

  15. @Zakhar

    Make sure to use to compatible version of Moq and Moq.Contrib. I will update this post in the future, however as of right now I don’t have any time.

    Andrew Kharlamov (July 15th, 2011)

TrackBack URL

Leave a comment