Basic guide on starting out with Moq

Moq is an open-source mocking library for .Net. It’s main strength is that it is very simple to use. In addition the library is making good use of C# language features like lambda expressions.

The quick start page is very well written and will tell you all you need to know to get started using the library.

While the quick start is great to tell you the how, I have seen several questions* on Stack Overflow that lead me the believe that the why and the when may be more difficult to grasp for someone starting out with Moq. I hope to clarify some of these issues in this post.

Some of the problems highlighted in these questions* is people mocking the class under test and mocking everything they can in their tests (every object, including framework containers).

We first need to understand what are mocks and why are they used. First of all mocks allow you to replace an object used by your test by supplying them with the equivalent of a stunt double, or rather a test double. Instead of calling the real object, the test code will call this test double.

The mock can supply canned responses to method calls and verify if a method has been called and how many times. When a mock is called, instead of executing the real method, Moq will supply a predetermined value without calling a real instance of the object.

In other words, we mock the objects we aren’t testing to facilitate the test on the objects we are testing. If the class under test is being mocked, that means we are providing canned responses for the method we are supposed to be testing. The method isn’t being called and thus isn’t being tested. Therefore never mock the class you are testing.

So why should we use a mocking library like Moq?

  • To abstract away dependencies
  • To test behaviour (via expectations) rather than results
  • To simplify test code by easily returning a desired value
  • To test only the class under tests

Abstracting away dependencies will allow you to test methods that rely on classes that haven’t been developed yet and that you only possess an interface for. This is a really neat feature when working with a test first approach.

Abstracting away dependencies will also concentrate your test on a single unit. Moreover dependencies are often slow or difficult to access. Tests that rely on dependencies tend to be flaky and untrustworthy. Did your test fail because it couldn’t connect to the database or did fail because of the logic of the method.

There are many types of testing (integration testing, unit testing, etc.). Ideally when doing pure unit testing you should mock all external dependencies on things like the file system, databases and web services. Following this rule will lead to tests that are more reliable and faster to execute. If you are doing continuous integration and plan to have your tests run automatically, these are two qualities your tests must possess if you want to process to go smoothly.

Example

Here is an example of using Moq. Here salesTax and rebate are both private constants defined on the test class.

[TestMethod]
public void CalculateSalesPrice_correctly_applies_rebate_and_sales_tax_to_an_item()
{
    // Arrange
    var mockTaxableItemSpecification = new Mock<ITaxableItemSpecification>();
    var mockRebateService = new Mock<IRebateService>();
    var item = new ItemDataBuilder().Build();

    var itemPriceCalculator
        = new itemPriceCalculator(mockTaxableItemSpecification.Object,
                                  mockRebateService.Object);

    mockTaxableItemSpecification.Setup(mock =>
            mock.IsValid(It.IsAny())).Returns(true);

    mockRebateService.Setup(mock =>
            mock.IsItemOnSale(It.IsAny())).Returns(true);

    mockRebateService.Setup(mock =>
            mock.GetRebateForItem(It.IsAny())).Returns(rebate);

    // Act
    var result = itemPriceCalculator.CalculateSalesPrice(item);

    // Assert
    Assert.AreEqual((item.Price - (item.Price * rebate)) * salesTax, result);
}

ItemPriceCalculator is the class being tested. It has two dependencies, ITaxableItemSpecification and IRebateService.

TaxableItemSpecification is another class that will be unit tested on it’s own. The class may or may not have been developed at the time of writing this test. We could also do a test to would test the integration of those two classes, but for now we want to concentrate on making sure the result of ItemPriceCalculator is correct, regardless of the correctness of TaxableItemSpecification. We will worry about TaxableItemSpecification in it’s own unit test.

As for RebateService, it’s a web service that allows us to check if an item is on sale, and if so, by how much. Connecting to this service in our tests would lead to all kinds of troubles. The service could be down, our request to the service could time out due to a slow network connection. Also, the actual items on sale would vary over time, thus tests that would consider item X as on sale would fail when later call to the web service would show the item has being not on sale anymore.

Conclusion

When developing a test using Moq, we should decide what we need to mock and understand why we are doing it, rather than go in with a guns blazing approach and try to mock everything.

*: For reference, here are some of the SO questions : q1, q2, q3, q4.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s