Useful tips and tricks when writing unit tests with Moq (Part II)

Some time ago I wrote an article about Moq with some tricks I used while unit testing my code.

In this article you will find some more tips that I found very useful while using the framework.

Reset the Verify counter before every unit test runs

By using the Verify method you can check if a method of your mocked object was called. However, if you have multiple unit tests that verify the call of a method, then the number of calls is added with each call to the method. Use the Clear method of the mocked object inside the Setup method:

[SetUp]
public void SetupBeforeEachTest()
{
    testMock.Invocations.Clear();
}

Assert for specific values of parameters of mocked methods

When using the Verify logic, I very often want to check if a mocked method was called with specific values. Here is how:

testMock.Verify(p =>
        p.TestMethod(It.Is<Person>(t => t.FirstName == "Christos")),
    Times.Once);

Here is also a StackOverflow question about this kind of check.

Mock classes which have a constructor with parameters

Classes might inject other objects through their constructor, so when you mock these classes, you will have to provide mocked implementation for these objects also. For that, simply add the mocked properties in the constructor when creating the mocked object. For more information, check this StackOverflow question.

Test asynchronous methods with Moq

Simply use the async Task keywords in the declaration of the unit test. You can then use the await keyword inside the body of the method:

public async Task TestMethod()
{
    // Arranges

    await mvcController.GetAll(model);

    // Asserts
}

Return a Task with value when you setup an async method

When you want to setup an async method of a mocked object, you might want that this method returns a specific result to the caller. The method has to return a Task with the value you define. For that you have two valid options:

personMock
    .Setup(r => r.GetPerson(It.IsAny<string>()))
    .Returns(Task.FromResult(new Person
    {
        Age = 34,
        LastName = "Monogios",
        FirstName = "Christos"
    }));
personMock
    .Setup(r => r.GetPerson(It.IsAny<string>()))
    .ReturnsAsync(new Person
    {
        Age = 34,
        LastName = "Monogios",
        FirstName = "Christos"
    });

Assert for thrown exceptions

When you want to verify that a method under test throws a specific type of exception then you can use the following Assert-check:

Assert.Throws<FormatException>(() => 
    _service.DummyMethod(firstName, lastName));

For async code use the following snippet and do not forget to define your test-method as async:

await Assert.ThrowsAsync<NullReferenceException>(() => _service.DummyMethodAsync(
    firstName, lastName));
comments powered by Disqus