Mocking functionality using MOQ

What is wrong with this code?

class Program
{
static void Main(string[] args)
{
DateTime dob = new DateTime(1967, 7, 9);
int days = CalcDays(dob);
Console.WriteLine($”Days: {days}”);
}

    private static int CalcDays(DateTime dob)
{
return (DateTime.Today – dob).Days;
}
}

Well, the code will work. But testing will become a problem because DateTime.Today is a non-deterministic function. That means that it is possible that the function will return a different value when called at different times. In this case it is clear that tomorrow the function will return something else than today or yesterday. So if you want to write a test for this function you’ll need to change it every day. And actually, changing a test to make it pass isn’t exactly the idea of unit testing…

How can we solve this?

There is some work involved here. Let me draw what we’re going to implement:

image

I have shown this pattern in previous posts already. We are injecting the IClockService into the Date class. In the actual implementation we then implement the CurrentDate property as DateTime.Today.

So now we can create our test project and write some tests. In the tests we will mock the IClockService so that CurrentDate becomes deterministic and we don’t have to modify our tests every day.

Our tests could look something like:

class FakeClockService : IClockService
{
public DateTime CurrentDate
{
get
{
return new DateTime(1980, 1, 1);
}
}
}

[TestClass()]
public class DateTests
{
[TestMethod()]
public void CalcDaysTest()
{
// arrange
Date dt = new Date(new FakeClockService());
DateTime dob = new DateTime(1967, 7, 9);

        // act
int days = dt.CalcDays(dob);

        // assert
Assert.AreEqual(4559, days);
}
}

As you can see I have implemented a FakeClockService that will always return a fixed date. So testing my code becomes easy.

But if I want to test my code with different fake values for CurrentDate I will need to implement the interface for each of these different values. In this simple case the interface contains 1 simple method, so besides messing up my code that is not a big problem. But when your interface becomes larger this becomes a lot of work.

Enter MOQ

According to their website, MOQ is “The most popular and friendly mocking framework for .NET”. I tend to agree with this.

Setting up MOQ

Starting to use MOQ is easy: in the test project install the MOQ Nuget package. This will set up your project to use MOQ. There are 2 possible ways to do this.

Using the GUI

In Visual Studio open the Nuget Package manager (Tools >  Nuget Package Manager >  Manage Nuget Packages for Solution… ) and find MOQ, then install the latest stable version.

Using the NugetPackage Manager Console

If you like typing then bring up the Nuget Package Manager Console (Tools >  Nuget Package Manager >  Package Manager Console). Make sure that in he Default Project your test project is selected and then type

install-package MOQ

image

You will now find 2 additional references in your project references : Mocking and Moq.

Using MOQ in your tests

[TestMethod()]
public void CalcDaysTestNegative()
{
// arrange
var mock = new Mock<IClockService>();
mock.Setup(d => d.CurrentDate).Returns(new DateTime(1960, 1, 1));

    Date dt = new Date(mock.Object);
DateTime dob = new DateTime(1967, 7, 9);

    // act
int days = dt.CalcDays(dob);

    // assert
Assert.AreEqual(-2746, days);
}

The Mock class resides in the Moq namespace so don’t forget to add

using Moq;

in your list of usings.

I set up the mock by calling the Setup method. In this method I actually say: “When somebody asks you to return the CurrentDate, then always give them Januari the first of 1960.”

The variable mock now contains an implementation of IClockService. I defined the CurrentDateproperty to return a new DateTime(1960, 1, 1) in 2 lines of code. This keeps my code clean because I don’t need to implement another fake class for this case. So my code stays clean and I can easily test all my border cases (such as when the 2 dates are equal).

To be complete: mock is not an IClockService, but this will be the mock.Object. So I pass mock.Object into the new Date( ). Now I have a deterministic function for my tests!

You will appreciate MOQ even more when your interfaces become larger. When you have an interface with 20 methods, and you only need 3 methods, then you just have to mock these 3 methods, not all 20. You can also mock classes with abstract or virtual functions in the same way.

Conclusion

This is by no means a complete tutorial on how to use MOQ. You can find a tutorial at https://github.com/Moq/moq4/wiki/Quickstart written by the MOQ guys themselves. There you can find more of the power of MOQ.

I did want to show that using a mocking framework like MOQ will allow you to write simpler tests, so you have one less excuse for not writing tests!

Also now you know my date of birth, so don’t forget to send me a card!

One more thing

I wanted to implement a simple GetAge(…) function, which should be easy enough. But then I read this thread on StackOverflow and I decided to keep things simple and just go with CalcDays(…). Call me a coward Knipogende emoticon

Happy testing!!

About Gaston

MCT, MCSD, MCDBA, MCSE, MS Specialist
This entry was posted in .Net, Codeproject, Development, OOAD, Testing and tagged . Bookmark the permalink.

1 Response to Mocking functionality using MOQ

  1. Pingback: Structuring an MVC app for easy testing | MSDev.pro blog

Leave a comment