Click here to Skip to main content
15,887,683 members
Articles / Moq

Mocking Functionality using MOQ

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
14 Mar 2016CPOL4 min read 8.9K   2  
Mocking functionality using MOQ

What is wrong with this code?

C#
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:

C#
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

C#
[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...

C#
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 January 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!!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect Faq.be bvba
Belgium Belgium
Gaston Verelst is the owner of Faq.be, an IT consultancy company based in Belgium (the land of beer and chocolate!) He went through a variety of projects during his career so far. Starting with Clipper - the Summer '87 edition, he moved on to C and mainly C++ during the first 15 years of his career.

He quickly realized that teaching others is very rewarding. In 1995, he became one of the first MCT's in Belgium. He teaches courses on various topics:
• C, C++, MFC, ATL, VB6, JavaScript
• SQL Server (he is also an MSDBA)
• Object Oriented Analysis and Development
• He created courses on OMT and UML and trained hundreds of students in OO
• C# (from the first beta versions)
• Web development (from ASP, ASP.NET, ASP.NET MVC)
• Windows development (WPF, Windows Forms, WCF, Entity Framework, …)
• Much more

Of course, this is only possible with hands-on experience. Gaston worked on many large scale projects for the biggest banks in Belgium, Automotive, Printing, Government, NGOs. His latest and greatest project is all about extending an IoT gateway built in MS Azure.

"Everything should be as simple as it can be but not simpler!" – Albert Einstein

Gaston applies this in all his projects. Using frameworks in the best ways possible he manages to make code shorter, more stable and much more elegant. Obviously, he refuses to be paid by lines of code!

This led to the blog at https://msdev.pro. The articles of this blog are also available on https://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=4423636, happy reading!

When he is not working or studying, Gaston can be found on the tatami in his dojo. He is the chief instructor of Ju-Jitsu club Zanshin near Antwerp and holds high degrees in many martial arts as well.

Gaston can best be reached via https://www.linkedin.com/in/gverelst/.


Comments and Discussions

 
-- There are no messages in this forum --