Two Ways to Count the Number of Times a Mocked Method is Called With Moq

Full source code available here.

When mocking a service you sometimes want to know how many times a method on that service was called, I had done this in the past and knew about Verify. This class has some static methods that let you check this in a variety of ways.

Another option is to use the CallBack method to increment a counter manually, then check that the counter has the expected value with an Assert.

The method call to test

I have a very simple library with a FooService that takes an IMathService as a constructor parameter. The implementation of IMathService doesn’t matter, what I want to check is the number of times the AddNumbers method is called.

Using Verify

This is probably the best way to go as Verify is designed for this exact purpose - to verify the number of times a method has been called.

Arrange - Inside the test method, mock the IMathService (line 5), setup up the AddNumbers method to return a known response to a specific invocation (line 6), create the FooService passing it the mocked MathService (line 8).

Act - Call the public method on the FooService. This should in turn call the AddNumbers method once on the mocked MathService (line 11).

Assert - Finally assert that the AddNumbers has been called once (line 15).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[Fact]
public void Check_Times_Called_With_Verify()
{
    // Arrange
    Mock<IMathService> mathService = new Mock<IMathService>();
    mathService.Setup(ms => ms.AddNumbers(1, 2)).Returns(3);
    
    FooService fooService = new FooService(mathService.Object);
    
    // Act 
    string result1 = fooService.AddMessageToAnswer("hello", 1, 2);

    // Assert
    Assert.Equal("hello 3", result1);
    mathService.Verify(ms => ms.AddNumbers(1, 2), Times.Exactly(1));
}

Using Callback

Another approach is to use the built-in Callback that can execute on each method that is Setup on a mocked service. Its syntax is simple, add the Callback after the Return. In this example, I use it to increment a counter (line 6).

The rest of the test is the same up to the Assert, where I check that counter has the expected value (line 16).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
[Fact]
public void Check_Times_Called_With_Callback()
{
    // Arrange
    int timesCalled = 0;
    Mock<IMathService> mathService = new Mock<IMathService>();
    mathService.Setup(ms => ms.AddNumbers(1, 2)).Returns(3).Callback(() => ++timesCalled);
    
    FooService fooService = new FooService(mathService.Object);
    
    // Act 
    string result = fooService.AddMessageToAnswer("hello", 1, 2);

    // Assert
    Assert.Equal("hello 3", result);
    Assert.Equal(1, timesCalled);
}

It.IsAny<>

Both approaches work with It.IsAny for params to the mocked method, or when asserting with the Verify. The attached zip file has examples of this.

Full source code available here.

comments powered by Disqus

Related