How to create fakes with Moq. And what I don't like about it

A recurring task when writing unit tests is creating replacements for collaborators. If you’re writing unit tests for an order delivery system, you don’t want to use a real payment gateway. You don’t want to charge a credit card every time you run your tests. This is how we can create fakes using Moq.

Fakes are testable replacements for real dependencies and external systems. They’re often called test doubles too. Fakes return a fixed value or throw an exception to test the logic around the real dependency they replace. You can either create fakes by hand or use a mocking library like Moq.

Roll your fakes

You can create your own fakes or doubles by hand. Yes, doubles like the body doubles in movies.

If you apply the Dependency Inversion Principle, the D of SOLID, your dependencies are well abstracted using interfaces. Each service receives its collaborators instead of build them.

To create a fake, create a class that inherits from an interface. Then, on Visual Studio, from “Quick Refactorings” menu, choose “Implement interface” option. Et voilà! you have your own fake.

But, if you need to create lots of fake collaborators, a mocking library can make things easier. Mocking libraries are an alternative to roll your own fakes. They offer a friendly API to create fakes for an interface or a class. Let’s see Moq, one of them!

Moq, a mocking library

Moq is a mocking library that “is designed to be a very practical, unobtrusive and straight-forward way to quickly setup dependencies for your tests”.

Moq, “the most popular and friendly mocking library for .NET”

From moq

Create fakes with Moq…Action!

Let’s see Moq in action! Suppose you have an OrderService that uses a IPaymentGateway and IStockService. This OrderService checks if there is stock available to then charge a credit card when placing a new order. Something like this,

public class OrderService 
{
  private readonly IPaymentGateway _paymentGateway;
  private readonly IStockService _stockService;

  public OrderService(IPaymentGateway paymentGateway, IStockService stockService)
  {
    _paymentGateway = paymentGateway;
    _stockService = stockService;
  }

  public OrderResult PlaceOrder(Order order)
  {
    if (!_stockService.IsStockAvailable(order))
    {
      throw new OutOfStockException();
    }

    _paymentGateway.ProcessPayment(order);
    return new PlaceOrderResult(order);
  }
}

To create a unit test for this service, let’s create replacements for the real payment gateway and stock service. We want to check what the OrderService class does when there’s stock available and when there isn’t.

For our test name, let’s follow the naming convention from The Art of Unit Testing. With this naming convention, a test name shows the entry point, the scenario and the expected result separated by underscores.

To learn about other naming conventions, check my post How to name your unit tests.

[TestClass]
public class OrderServiceTests
{
  [TestMethod]
  public void PlaceOrder_StockAvailable_CallsProcessPayment()
  {
    var fakePaymentGateway = new Mock<IPaymentGateway>();

    var fakeStockService = new Mock<IStockService>();
    fakeStockService.Setup(t => t.IsStockAvailable(It.IsAny<Order>()))
                    .Returns(true);
    var orderService = new OrderService(fakePaymentGateway.Object, fakeStockService.Object);

    var order = new Order();
    orderService.PlaceOrder(order);

    fakePaymentGateway.Verify(t => t.ProcessPayment(order), Times.Once);
  }
}

What happened here? First, it creates a fake for IPaymentGateway with new Mock<IPaymentGateway>(). Moq can create fakes for classes too.

Then, it creates another fake for IStockService. This fake returns true when the method IsStockAvailable is called with any order as parameter.

Next, it uses the Object property of the Mock class to create instances of the fakes. With these two instances, it builds the OrderService.

Finally, using the Verify method, it checks if the method ProcessPayment was called once. A passing test now!

Cut!…What I don’t like about Moq

Moq is easy to use. You can start using it in minutes! You only need to read the README file and the quickstart files in the documentation. But…

For Moq, everything is a mock, Mock<T>. Strictly speaking, everything isn’t a mock.

The XUnit Tests Patterns book presents a detailed category of fakes or doubles: fakes, stubs, mocks, dummies and spies. And, The Art of Unit Testing book reduces this classification to only three types: fakes, stubs and mocks. Other libraries use Fake, Substitute or Stub/Mock instead of only Mock.

Moq has chosen this simplification to make it easier to use. But, this could lead to misusing the term mock. Notice I have deliberately used the word “fake” instead of “mock” so far.

If you want to learn the difference between stubs and mocks, check What are fakes in unit testing.

For Moq, MockRepository is a factory of mocks. You can verify all mocks created from this factory in a single call. But, a repository is a pattern to abstract creating and accessing records in a data store. You will find OrderRepository or EmployeeRepository. Are MockSession or MockGroup better alternatives? Probably. Naming is hard anyways.

Conclusion

Voilà! That’s how you can create fakes and mocks with Moq. Moq is a great library! It keeps its promise. It’s an straight-forward library to setup dependencies in your tests. You need to know a few methods to start using it. You only need Setup, Returns, Throws and Verify. It has chosen to lower the barrier of writing tests. Give it a try! To mock or not to mock!

For more tips on writing unit tests, check my posts How to write good unit tests? and Have a failing test. If you use Moq often, avoid typing the same method names all the time with these snippets I wrote for Visual Studio.

Happy mocking time!