Creating Mock Objects for C# Unit Tests, using Moq

In my demonstration of the Dependency Injection design pattern, I manually created a mock object. This let me perform unit tests without needing to access a database.

Here is how you can use the Moq library, to eliminate writing the code for manual mock classes.

If you aren’t familiar with dependency injection, please read this article first.

 

Video version of this demonstration

 

Manual mock object version

 

IPlayerDataMapper.cs

This defines the functions needed in the object that is “injected” into the CreateNewPlayer function – by both the “real” object (which acceses the database), and the “mock” object (which doesn’t need a database).

 

PlayerDataMapper.cs

This class implements IPlayerDataMapper, and accesses the database – making it difficult to use in automated tests.

 

Player.cs

The CreateNewPlayer function does some validation, using the “injected” (passed in, as a parameter) IPlayerDataMapper object.

 

MockPlayerDataMapper.cs

This is the manually-created mock class, to use in the unit tests.

If you had a large program, you might need to create dozens, or hundreds, of mock classes – to prevent your unit tests from needing to access external resources (e.g., databases, web services, the file system).

 

TestPlayer.cs

These are the unit tests, using MockPlayerDataMapper objects to eliminate the need to connect to a database when running automated tests.

 

Simpler mock objects, using Moq

Add Moq to the unit test project, using NuGet

If you aren’t familiar with it, NuGet is a Visual Studio tool to add some third-party libraries to projects.

You could find the library files online (Moq’s are at https://github.com/moq/moq4), download them, and add them as a reference to your project. However, NuGet will do all that for you, with a nice user interface.

Right-click on the TestEngine project (the one we want to add Moq to). Select “Manage NuGet Packages…”

Right-click on the unit tst project, and select "Manage NuGet Packages...", to add Moq to the project

 

In the NuGet tab, select “Browse” and search for “Moq” – the library we want to add.

In the NuGet tab, select "Browse" and enter "Moq" in the search box

There are several add-on libraries that make it easier to use Moq in different types of programs. But, for now, we will only add the one named “Moq”, with over seven million downloads.

Click on the row with “Moq”, and you will see an “Install” button to the right of it.

Click the "Install" button, to add Moq to the project

You will see more information about the library, including any dependencies it has – such as version of the .NET Framework.

Click the “Install” button, to add Moq to the project.

When it is done, you can view the “References” in “TestEngine”, and you should see “Moq”.

 

Create unit tests that use Moq

Because we already have an existing TestPlayer class, I’ll make a copy of it. We’ll modify that unit test class, replacing the mock objects from the manually-created mock class with objects created by Moq.

This is the new TestPlayer class:

 

To use the Moq library, we need to add “using Moq;” (see line 4).

In the unit tests, instead of creating an object of the old MockPlayerDataMapper, and passing it into the Player.CreateNewPlayer function, we will use Moq to create the mock object.

Line 24 is how Moq creates an object that implements the IPlayerDataMapper interface.

For this first test, we don’t need to configure that object to do any specific behavior, when it is called. So, we only need to change line 26, to pass in the “Object” property of the “mock” object. This is the object that will be used inside the CreateNewPlayer function, during this unit test.

 

The power of Moq is that you can configure your mock object to return any results you want.

In the Test_CreateNewPlayer_AlreadyExistsInDatabase unit test, when the CreateNewPlayer function calls PlayerNameExistsInDatabase, we want the mock object to return “true”.

For this unit test, I don’t care what value is passed into the PlayerNameExistsInDatabase function. I know it will be “Test” (from line 38), but that is not important for this test. I also know that I want that function to return “true”, regardless of the value passed into it (for this test).

This is what line 36 does.

It configures, by using the “Setup” function on the mock object, the PlayerNameExistsInDatabase to accept any string parameter (the “It.IsAny<string>()” and have it “Returns(true)”.

If I was building a more complex test, I could create multiple “Setup” lines, and have the mock object return different results, based on different parameters I might pass in. But, for this simple test, we only need the one setup line.

On line 49, we have the same setup, but tell Moq to have the function return “false” – because that is the scenario we want to test in this unit test.

 

To see more about what you can do with Moq (including more complex test scenarios), you can view the Moq Quickstart page, or read Roy Osherove’s “The Art of Unit Testing: with examples in C#”.