Stub vs Mock when unit testing

Daniel Hansen picture Daniel Hansen · Feb 26, 2014 · Viewed 17.6k times · Source

I have lately become very interested in testing and Im now trying to learn to do unit testing in the best way possible. I use NUnit together with Rhino Mocks. I have also been reading a lot over here at Stackoverflow but havent been able to find a clear answer to my question.

What I wonder is if I have a method like the below, should I mock the OfficeClass dependency and also test GetAllOffices or only use a stub for the dependency and verify that the method GetAllOffices has been called and that I indeed get the offices back that I expected from my setup for the stub?

public Offices GetAllOffices() 
{
    try
    {
        var offices = officeClass.GetAllOffices();
        return offices;
    }
}

Will it make any difference if the OfficeClass is just another POCO or if it is let say a web service in sence of mocking vs stubbing?

Long question short: When to Mock and when to Stub in unit testing?

Answer

nerdybeardo picture nerdybeardo · Feb 26, 2014

Mocks use a framework to generate a "mock" of your dependency. For example if officeClass is a repository for your data then you can use a mock framework (I use MOQ) to generate a mock of your repository. That's why using interfaces for your dependency make it ideal for testing, the mocking framework can easily make a mock of an interface for testing.

With stubs as I understand it, you manually stub out your dependency and create canned responses. For example if you have an interface IOfficeClass and you create a new class that inherits from it, you can inject that class into your service to allow you to use it.

Again things like web services should be wrapped in some interface (like the IRepository pattern), that will allow you to easily test your logic without needing to hit the web service. The same with POCO classes.

So for example in your case you would have:

public interface IOfficeRepository
{
    IQueryable<Office> GetAll();
}

And for your service

public class MyOfficeService
{
    private readonly IOfficeRepository officeRepostiory;

    public MyOfficeService(IOfficeRepository repository)
    {
        this.officeRepostiory = repository;
    }

    public Office GetOffice(int id)
    {
        return this.officeRepostiory.GetAll().SingleOrDefault(o => o.Id == id);
    }
}

This way you can also change your underlying datasource without having to modify your main application or business logic code.

Your unit test would look something like this using moq:

[TestClass]
public class OfficeUnitTest
{
    private MyOfficeService service;

    [TestInitialize]
    public void Setup()
    {
        var officeRepository = new Mock<IOfficeRepository>();

        var office = new List<Office>();
        office.Add(new Office{ Id = 1 });

        officeRepository.Setup(m => m.GetAll()).Returns(office.AsQueryable());

        this.service = new MyOfficeService(officeRepository.Object);
    }

    [TestMethod]
    public void TestGetById()
    {
        Assert.IsNotNull(service.GetOffice(1));

        // my mock will never return a value for 2
        Assert.IsNull(service.GetOffice(2));
    }
}

You can read more about mocks and stubs below:

http://martinfowler.com/articles/mocksArentStubs.html

http://msdn.microsoft.com/en-us/library/ff649690.aspx