Master C#

How to use Moq to ease unit testing in C#

Take advantage of the Moq open source library to isolate application code from dependencies for testing

How to use Moq to ease unit testing in C#
Getty Images

Master C#

Show More

We often need to write unit tests for code that accesses an external resource such as a database or a file file system. If such resources are not available, the only way to ensure that the tests can execute is by creating mock objects. In essence, by drawing on fake implementations of these underlying dependencies, you can test the interaction between the method being tested and its dependencies. Three of the most popular mocking frameworks for .Net developers are Rhino Mocks, Moq, and NMock.

Among these, Moq may be the most flexible and easy to use. The Moq framework provides an elegant way to set up, test, and verify mocks. This article presents a discussion of Moq and how it can be used to isolate units of code from their dependencies.

Getting started with Moq

You can use Moq to create mock objects that simulate or mimic a real object. Moq can be used to mock both classes and interfaces. However, there are a few limitations you should be aware of. The classes to be mocked can’t be static or sealed, and the method being mocked should be marked as virtual. (Note there are workarounds to these restrictions. You could mock a static method by taking advantage of the adapter design pattern, for example.)

The first step in using Moq is to install it so that you can use it in your unit test project. You can download Moq from GitHub and add references as appropriate. However, I prefer installing Moq via NuGet because it is both easier and less likely to miss references. You can install Moq by using the following command at the NuGet command line.

Install-Package Moq

How to mock interfaces using Moq

Let’s start by mocking an interface. The syntax for creating a mock object using the Mock class is given below.

Mock<TypeToMock> mockObjectType=new Mock<TypeToMock>();

Now, consider the following interface named IAuthor.

public interface IAuthor
    {
        int Id { get; set; }
        string FirstName { get; set; }
        string LastName { get; set; }
    }

Using the Moq framework, you can create a mock object, set property values, specify parameters, and return values on the method calls. The following code snippet illustrates how you can create an instance from the IAuthor interface using Moq.

var mock = new Mock<Author>();

Note that the Mock class belongs to the Moq framework and contains a generic constructor that accepts the type of interface you want to create. Moq takes advantage of lambda expressions, delegates, and generics. All of this makes using the framework very intuitive.

The following code snippet shows how you can mock the IAuthor interface and provide the properties of the mocked instance with the appropriate values. Note how we use Assert to verify the values of the properties of the mocked instance.

var author = new Mock<IAuthor>();
author.SetupGet(p => p.Id).Returns(1);
author.SetupGet(p => p.FirstName).Returns(“Joydip”);
author.SetupGet(p => p.LastName).Returns(“Kanjilal”);
Assert.AreEqual(“Joydip”, author.Object.FirstName);
Assert.AreEqual(“Kanjilal”, author.Object.LastName);

How to mock methods using Moq

Let’s now consider the following class named Article. The Article class contains just one method called GetPublicationDate that accepts an article Id as parameter and returns the publication date of the article.

public class Article
    {
        public virtual DateTime GetPublicationDate(int articleId)
        {
            throw new NotImplementedException();
        }
    }

Because the GetPublicationDate method is not yet implemented in the Article class, the method has been mocked to return the current date as the publication date, as shown in the code snippet given below.

var mockObj = new Mock<Article>();
mockObj.Setup(x => x.GetPublicationDate(It.IsAny<int>())).Returns((int x) => DateTime.Now);

The Setup method is used to define the behavior of a method that is passed to it as a parameter. In this example, it is used to define the behavior of the GetPublicationDate method. The call to It.IsAny<int>() implies that the GetPublicationDate method will accept a parameter of type integer; It refers to a static class. The Returns method is used to specify the return value of the method that is specified in the Setup method call. In this example, the Returns method is used to specify the return value of the method as the current system date.

Moq allows you to verify whether a particular method or a property was called. The following code snippet illustrates this.

mockObj.Verify(t => t.GetPublicationDate(It.IsAny<int>()));

Here we’re using the Verify method to determine if the GetPublicationDate was called on the mock object.

How to mock base class methods using Moq

Consider the following piece of code. We have two classes here—the RepositoryBase class and the AuthorRepository class that extends it.

public abstract class RepositoryBase
{
    public virtual bool IsServiceConnectionValid()
    {
        //Some code
    }
}
public class AuthorRepository : RepositoryBase
{
    public void Save()
    {
        if (IsServiceConnectionValid())
        {
            //Some code
        }
    }
}

Now suppose we want to check if the database connection is valid. However, we may not want to test all the code inside the IsServiceConnectionValid method. For instance, the IsServiceConnectionValid method might contain code that pertains to a third-party library. We would not want to test that, right? Here is where the CallBase method in Moq comes to the rescue. 

In situations like this, where you have a method in the base class that has been overridden in the mocked type, and you need to mock the base version of the overridden method only, you can draw on CallBase. The following code snippet shows how you can create a partial mock object of the AuthorRepository class by setting the CallBase property to true.

var mockObj = new Mock<AuthorRepository>(){CallBase = true};
mockObj.Setup(x => x.IsServiceConnectionValid()).Returns(true);

The Moq framework makes it easy to create mock objects that mimic the behavior of classes and interfaces for testing, with just the functionality you need. For more on testing with mocks, check out this great article from Martin Fowler.  

Copyright © 2018 IDG Communications, Inc.