Mocking .NET Objects with NUnit

NUnit is my Unit Testing tool of choice for .NET development. Microsoft provides a unit testing framework but it only works with some higher-end versions of Visual Studio. They’re so similar that it’s almost ridiculous that Microsoft created their own version.
(See one of my previous posts for more information on Automating NUnit with MSBuild.) In the Java world it’s fairly common to do Mocking to help make unit testing easier. I’ve written about using JMock for Unit Tesing in Java. In this post, I’d like to talk about a relatively new feature of NUnit which now supports Mocks out of the box.

What Are Mock Objects

Mock Objects are a technique that allow you to isolate classes from their dependencies for testing purposes. This isolation allows for fine-grained testing of single methods in a single class, possibly even before the dependent classes are fully implemented. This isolation allows your tests to run quickly and it makes testing small pieces of functionality much easier. When you’ve tested individual pieces of code in isolation you can have much higher confidence in larger-grained tests. This isolation becomes even more interesting when you are dealing with dependencies such as a data layer or a web service layer. External calls like that can be very time consuming or could fail if the remote system is down for maintenance.

One of the great things about using Mock Objects is that they force you to think about the dependencies that your classes and methods have. It forces you to think about the coupling between your classes. If you have high coupling then your code is often harder to test. If you have a loosely coupled design then testing and using Mock Objects is very much easier. Thinking about those design notions early can help you more easily manage change over time.

Maxims:

  • Good design is better than bad design
  • Loosely coupled objects are usually a better design than tightly coupled objects
  • Testing improves code quality and developer efficiency over time
  • Testing is easier with a loosely coupled designs

A Sample Project

We’re going to start with some simple code. We create a Domain object called Person and an interface for a Data Access object called IPersonRepository. Pretty simple at this point.

public class Person
{
public string Id;
public string FirstName;
public string LastName;
public Person(string newId, string fn, string ln)
{
Id = newId;
FirstName = fn;
LastName = ln;
}
}


public interface IPersonRepository
{
List GetPeople();
Person GetPersonById(string id);
}

Next we create a PersonService object. This would represent all of the business logic in our application. It would interact with the Data Access tier and return information to the UI layer for display.

We wire together our objects using Constructor based Dependency Injection. All of the dependent Objects are sent in through the constructor. This allows for the loose coupling since the PersonService doesn’t know about the Implementing class, but only the interface. Since it’s done in the constructor we can also never have an invalid PersonService as would be the case if there was a setter for the IPersonRepository implementation.

This is again a fairly straightforward implementation, but I hope enough to display the issue at hand.

public class PersonService
{
private IPersonRepository personRepos;
public PersonService(IPersonRepository repos)
{
personRepos = repos;
}
public List GetAllPeople()
{
return personRepos.GetPeople();
}
public List GetAllPeopleSorted()
{
List people = personRepos.GetPeople();
people.Sort(delegate(Person lhp, Person rhp) {
return lhp.LastName.CompareTo(rhp.LastName);
});
return people;
}
public Person GetPerson(string id)
{
try
{
return personRepos.GetPersonById(id);
}
catch (ArgumentException)
{
return null; // no person with that id was found
}
}
}

Using Mocks with NUnit

Now we can start testing our PersonService. Notice that we haven’t even implemented the IPersonRepository yet. That way we can make sure that everything in our PersonService class works as expected without having to think about other layers of the application.


using System;
using System.Collections.Generic;
using NUnit.Framework;
using NUnit.Mocks;
[TestFixture]
public class PersonServiceTest
{
// The dynamic mock proxy that we will use to implement IPersonRepository
private DynamicMock personRepositoryMock;
// Set up some testing data
private Person onePerson = new Person("1", "Wendy", "Whiner");
private Person secondPerson = new Person("2", "Aaron", "Adams");
private List peopleList;
[SetUp]
public void TestInit()
{
peopleList = new List();
peopleList.Add(onePerson);
peopleList.Add(secondPerson);
// Construct a Mock Object of the IPersonRepository Interface
personRepositoryMock = new DynamicMock(typeof (IPersonRepository));
}
[Test]
public void TestGetAllPeople()
{
// Tell that mock object when the "GetPeople" method is
// called to return a predefined list of people
personRepositoryMock.ExpectAndReturn("GetPeople", peopleList);
// Construct a Person service with the Mock IPersonRepository
PersonService service = new PersonService(
(IPersonRepository) personRepositoryMock.MockInstance);
// Call methods and assert tests
Assert.AreEqual(2, service.GetAllPeople().Count);
}
[Test]
public void TestGetAllPeopleSorted()
{
// Tell that mock object when the "GetPeople" method is called to
// return a predefined list of people
personRepositoryMock.ExpectAndReturn("GetPeople", peopleList);
PersonService service = new PersonService(
(IPersonRepository) personRepositoryMock.MockInstance);
// This method really has "business logic" in it - the sorting of people
List people = service.GetAllPeopleSorted();
Assert.IsNotNull(people);
Assert.AreEqual(2, people.Count);
// Make sure the first person returned is the correct one
Person p = people[0];
Assert.AreEqual("Adams", p.LastName);
}
[Test]
public void TestGetSinglePersonWithValidId()
{
// Tell that mock object when the "GetPerson" method is called to
// return a predefined Person
personRepositoryMock.ExpectAndReturn("GetPersonById", onePerson, "1");
PersonService service = new PersonService(
(IPersonRepository) personRepositoryMock.MockInstance);
Person p = service.GetPerson("1");
Assert.IsNotNull(p);
Assert.AreEqual(p.Id, "1");
}
[Test]
public void TestGetSinglePersonWithInalidId()
{
// Tell that mock object when the "GetPersonById" is called with a null
// value to throw an ArgumentException
personRepositoryMock.ExpectAndThrow("GetPersonById",
new ArgumentException("Invalid person id."), null);
PersonService service = new PersonService(
(IPersonRepository) personRepositoryMock.MockInstance);
// The only way to get null is if the underlying IPersonRepository
// threw an ArgumentException
Assert.IsNull(service.GetPerson(null));
}
}

The PersonService doesn’t have a lot of logic in it, but I hope this illustrates how you easily can test various conditions using Mock objects. It also illustrates the idea of testing early by allowing you to test some code before all of the dependent objects are implemented.

While the Mocks built into NUnit might not be the most powerful or complete Mocking library out there, it should be sufficient for most uses. I’m sure they will continue to improve them over time as well, so I look forward to them becoming more powerful (and having better documentation) in the future.

Download Code Example:
NMock C# Example Project

For more on NUnit you might like to check out:

34 Replies to “Mocking .NET Objects with NUnit”

  1. I tried the above example using my own classes, but I get this:

    at System.Runtime.Remoting.Proxies.RealProxy..ctor(Type classToProxy, IntPtr stub, Object stubData)
    at NUnit.Mocks.DynamicMock.get_MockInstance()
    at SerialWidgetTest_Test.SSHStreamTest.Test1() in C:\WORK\firmware\Helpers\C#\trunk\TestWidgets\TestWidget_NUnit\SSHStreamTest.cs:line 27

    I’m not even sure what that means. Is the type of object I’m trying to mock too complex?

  2. Christopher,
    Was that an ArgumentException? Using this technique and NMock you can only mock things based on an Interface, not a concrete types. Using an interface is a good practice anyway because it leads to a looser coupling of your objects.

    If your really must mock concrete classes (you want to give up loose coupling, or are dealing with dependencies that were not written by you), you might want to look at another Mocking framework like Rhino Mocks.

    Hope that helps.

  3. Hi Geoff

    Im wading my way through loose coupling using interfaces. Forcing me to think about my dependencis before I code. What would be a quick example of your classes using asp.net as a GUI using the above example?

    Regards
    Chad

  4. Chad,
    In a Real application the Service would likely implement an Interface as well. You could then call the Service from UI code. Using ASP.NET, you would likely need to use a framework like Spring .NET to wire together your dependencies. If you do that though, you can then inject those dependencies into your Pages.


    public class ViewPerson : Page {
    private IPersonService personService;
    protected void Page_Load(object sender, EventArgs e)
    {
    Person person = personService.GetPerson(Request.QueryString["personId"]);
    // ... do something with person
    }
    }

    That doesn’t necessarily help a lot with Unit Testing though. Web/UI code is hard to unit test. Your best bet is to keep your UIs very thin, with very little code, and use it merely as a translation layer to get things out of the Web context and into “plain code” context. Then you can Unit Test all of the other code and leave testing of UIs to functional tests.

  5. @Chad
    Very good article and very well explained. This will help developers to understand mock object.

    @Geoff
    Using the scenario above I agree it is very hard to unit test, but we can use to MVP design pattern to unit test our code.

  6. Nice example, although you should be calling verify() on the mock, to make sure all expected behaviour/calls were performed by the mock

  7. Thanks for the post. But I can’t get this to work. I constantly get the following error:
    Could not load type ‘NUnit.Framework.Constraints.IResolveConstraint’ from assembly ‘nunit.framework

    I have tested both NUnit 2.4.x and NUnint 2.5.x Does anyone have a clue?

  8. Hi!
    You should try Rhino Mocks. The latest version supports AAA style and the other advantage is you don’t have to use string to identify methods. A big plus during auto-refactoring (using resharper etc).

    Thanx

  9. Hi

    Thanks a lot. Very good example. And so simple to understand for the beginners. I tried execute this example. But I got stucked “private DynamicMock personRepositoryMock;” in this statement. Here what actualy ‘DynamicMock’ stands for? Whether its a class or interface? I’m getting this Error:
    “The type or namespace name ‘DynamicMock’ could not be found (are you missing a using directive or an assembly reference?)” . Please help me to resolve this problem.

  10. Hi

    Thanks a lot. Very good example. And so simple to understand for the beginners. I tried execute this example. But I got stucked “private DynamicMock personRepositoryMock;” in this statement. Here what actualy ‘DynamicMock’ stands for? Whether its a class or interface? I’m getting this Error:
    “The type or namespace name ‘DynamicMock’ could not be found (are you missing a using directive or an assembly reference?)” . Please help me to resolve this problem.

  11. Hey great article. I have been searching several posts trying to understand the concept of mock testing, and you made me understand it… Thank very much!

  12. I’m trying to learn how to use the NUnit testing framework and mocking framework with VB.NET. This is a great example of how to use DynamicMock so I tried to “translate” it into VB. When I got to this line:

    personRepositoryMock = new DynamicMock(typeof (IPersonRepository));

    it was not obvious what the “equivalent” VB code would be because “typeof” is used a little differently in that language. The answer turns out to be:

    personRepositoryMock = New DynamicMock(GetType(IPersonRepository))

    which perhaps would have been obvious to experienced VB developers but was not to me.

  13. @Kim,
    You could mock Person if you were testing the PersonRepository, but Person has no real behavior (it’s just a data transfer object) in this example, so it probably wouldn’t provide any value to mock it out.

  14. I think I get your point Jeff.

    I’m pretty new to this whole testing/mocking thing and I’m kinda stuck right now. I understand the example above, but how do we test that the actual implementation of the repository works?

    I’ve build a small application using the MVVM pattern. The model is build with the Entity Framework. I’ve got a repository that performs crud operations on the model. any ideas of how to test that repository?

    cheers

  15. @Kim,
    Mocking is used to isolate pieces of code from other dependencies (either code or external systems). If you want to test code that connects to a database, for example, then you are doing integration testing. Just make sure to keep the integration tests separate from the unit tests because they will run slower and have dependencies on the setup, structure and contents of the database. With database integration tests you’ll probably want to run against a blank database and run the tests in transactions that are rolled back so that you can run them repeatedly.

    Hope that helps.

  16. @Geoff,
    thx for the quick response.
    I’m starting to get I think. Let me see if I get this right. The reason for mocking the repository is that it properly has dependencies to a database or some other kind of storage. And the personRepositoryMock.ExpectAndReturn(“GetPeople”, peopleList); is not actual testing if the repository works just the GetPeople() method from the repository gets called..right?

  17. @Kim,
    Right. We’re testing the logic of the repository itself and not the data access portions of it. Mocking is not only used for databases and storage though, it’s used for isolating a class from any of its dependencies so you can test just that single class and not the interaction of a lot of classes.

  18. @Geoff,
    thanks, I appreciate your help! So if I wanted to perform unit tests on Entity Framework generated entities I would have to find some way to mock those entities?

  19. I have an odd question…

    Why are we using mocking in this case ?
    PersonService service = new PersonService(
    (IPersonRepository) personRepositoryMock.MockInstance);
    Why don’t we use just a new concrete implementation of IPersonRepository ?

    In fact, I use Microsoft Moles in order to mock my objects. Here I see that we just can mock interfaces so we can do concrete implementation rather than mocking, isn’t it?

  20. @Julien,
    You could use a test instance of the IPersonRepository. That technique is generally called “Stubbing” you’re providing a fixed implementation of a dependency to test against. The advantage of Mocking is that you can generally more easily express different behaviors without writing a bunch of concrete stubs. For example, if you want to test both a successful and an exceptional condition, it’s very easy to mock that out where with Stubs you might have to write two different stub classes.

    Either technique can be used to isolate code for testing though.

  21. @Geoff
    Thanks for your answer, I can now see why it is useful :)

    (PS: It’s really great that you answer every question that way)

  22. I really appreciate this tutorial – it made it much easier for me to learn how to use mocks in NUnit and I was able to simplify some tests that depended upon access to a live database using this technique. Thanks!

  23. Hi Geoff Lane, i fined this post very useful as a newbie to testing.
    For the pass two month i have been struggling to test my class the connect to a database to read data.
    Is this possible, if yes please give a sample demo.
    Thank you so much for the help you a doing.

  24. Thanks for the very informative article. Even after all these years it’s still useful.

    I’m just exploring NUnit with some old .Net 1.1 code. Though NUnit keeps telling me that they now use NSubstitute I can’t use it because of the old .Net framework. When I use DynamicMock there’s a warning message about the object being superseded but I’m hoping I can ignore that and carry on.

    Does anyone know of any better mocking frameworks that can be used with VB.Net 1.1?

Leave a Reply

Your email address will not be published. Required fields are marked *