Moq and NUnit – Abstract and interface types

Effectively unit testing code using Moq and NUnit is a breeze and a pleasure.  If you’re not currently unit testing your code, and you’re interested in getting started, please take a look at my C# Writing unit tests with NUnit and Moq tutorial.

Mocking interfaces and abstract classes using Moq is no more complicated than mocking any other type.  There are just a couple of things to look out for.

Mocking Interfaces

Assume the following interface;

public interface IVehicle
{
    int BHP { get; set; }
    bool HasWheels { get; }
    int Wheels { get; }

    bool Move();
}

And the following unit test;

[Test]
public void IVehicle_Move()
{
    Mock vehicle = new Mock();

    int wheels = vehicle.Object.Wheels;

    Assert.IsTrue(wheels == 0);
}

As far as I know, there is no way to specify a concrete implementation to use when mocking an interface.  By default, Moq will return the default value for each property on the interface, and does nothing when void methods are execute.  If you want to override this behaviour, you must tell Moq what to do when the property/method is accessed;

[Test]
public void IVehicle_Move()
{
    Mock vehicle = new Mock();

    vehicle.Setup(t => t.Wheels).Returns(4);
    vehicle.Setup(t => t.Move()).Callback(() => Console.WriteLine("Move was called"));

    int wheels = vehicle.Object.Wheels;

    Assert.IsTrue(wheels == 0);
    vehicle.Verify(t => t.Move(), Times.Exactly(1));
}

The above test obviously fails miserably, but this is just a contrived example to make the point.  You use the Setup method on your mock object with the Callback method to override the default behaviour.

Abstract Classes

Abstract classes are subtly different.  Take the following abstract class;

public abstract class Vehicle : IVehicle
{
    public int BHP { get; set; }

    public bool HasWheels
    {
        get
        {
            return Wheels > 0;
        }
    }

    public abstract int Wheels { get; }

    public string WhoYouGonnaCall
    {
        get
        {
            return "Ghostbusters";
        }
    }

    public abstract bool Move();
}

The class itself is marked as abstract, meaning it cannot be directly instantiated.  The class contains an mix of abstract methods/properties and non-abstract properties.

Assuming the following unit test;

[Test]
public void Vehicle_Move()
{
    Mock vehicle = new Mock();

    int wheels = vehicle.Object.Wheels;

    Assert.IsTrue(wheels == 0);
}

As Wheels is abstract, it has no direct implementation, there Moq will return the default value of the properties data type (Int32, default value of 0).  However, the property WhoYouGonnaCall is not abstract, meaning it can be intercepted.  Take the following test;

[Test]
public void Vehicle_WhoYouGonnaCall()
{
    Mock vehicle = new Mock();

    string gonnaCall = vehicle.Object.WhoYouGonnaCall;

    Assert.AreEqual(gonnaCall, "Ghostbusters");
}

The property WhoYouGonnaCall is not mocked and its original value is returned rather than the default value of string.

Summary

Moq can easily be used to unit test abstract and interface types.  The process is the same as mocking any other type, just with subtle differences in behaviour to look out for.