BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

Testing
.NET 3.5+

Verifying the Number of Calls to a Mocked Method

The use of mock objects within unit tests allows you to verify that the correct calls to dependencies are made when a test is run. Rather than simply checking that a call is made, it is often essential to check how many times a method was executed.

Times Class

When using mock objects created with the Moq framework, you can verify that a method is called or that a property is accessed when a test is executed. In the Automated Unit Testing tutorial I briefly touched upon the idea that you can verify the number of times that a member is used, either with specific parameters or with arguments that match a predicate defined in a lambda expression. In the "Using Mocks" article I described the use of the Times structure and the static Exactly method for this purpose. In this article I will expand upon the earlier text and describe all of the options provided by the Times structure.

Sample Class

To demonstrate how the number of calls can be verified we need a class to test and a dependency to mock. We will use the code shown below. The ChangeReturner class controls the mechanism for returning change from a vending machine. This class includes a single method that processes the amount of change that is required following a transaction. The change can be given using coins of various denominations, including 1p, 2p, 5p, 10p, 20p, 50p, £1 and £2. To return a single coin, the class calls upon a dependency that implements the ICoinRelease interface, which is provided using constructor injection. The ICoinRelease interface is the type that we shall mock.

public interface ICoinRelease
{
    void Release(int denomination);
}


public class ChangeReturner
{
    ICoinRelease _coinRelease;
    IList<int> _denominations = new List<int> { 1, 2, 5, 10, 20, 50, 100, 200 };

    public ChangeReturner(ICoinRelease coinRelease)
    {
        _coinRelease = coinRelease;
    }

    public void GiveChange(int value)
    {
        int remainder = value;
        while (remainder > 0)
        {
            int coin = _denominations.Where(c => c <= remainder).Max();
            _coinRelease.Release(coin);
            remainder -= coin;
        }
    }
}

Times.Once

If you verify a mock object call without specifying the number of times that you expect it to have been executed, the verification will pass if at least one call was made. If the method was called a hundred times, the verification will still pass. Only if the method was not called at all will an exception be thrown causing the test to fail.

Sometimes you will want to ensure that a method is only called once. To do so, you can use the Once method of the Times structure with no arguments. In the following test fixture the ChangeReturner class is used to release one penny of change. The call to the mock's Verify method includes the code, "Times.Once()" as the second argument to ensure that only a single penny is released. If the class calls the mocked method with the argument, "1", more than once or not at all, the test will fail.

[TestFixture]
public class ChangeReturnerTests
{
    Mock<ICoinRelease> _mockCoinRelease;
    ChangeReturner _returner;

    [SetUp]
    public void SetUp()
    {
        _mockCoinRelease = new Mock<ICoinRelease>();
        _returner = new ChangeReturner(_mockCoinRelease.Object);
    }

    [Test]
    public void WhenReturningOnePenny()
    {
        _returner.GiveChange(1);
        _mockCoinRelease.Verify(m => m.Release(1), Times.Once());
    }
}

Times.Never

As well as ensuring that a method is called, it can be equally useful to verify that a method is not run. For example, in our change returning mechanism we may want to test that no coins are released when the correct amount of money is given. The following test uses Times.Never in the second parameter of the Verify method. If any coins are returned when the change amount is zero, the test fails.

[Test]
public void WhenReturningNoChange()
{
    _returner.GiveChange(0);
    _mockCoinRelease.Verify(m => m.Release(It.IsAny<int>()), Times.Never());
}

Times.Exactly

If you want to specify any other specific number of expected calls, you should use the Exactly method. This method accepts a single integer argument that defines the number of times that the method should be executed with the parameters defined in the lambda expression. The following test checks that when four pounds of change is given, the machine releases two £2 coins.

[Test]
public void WhenReturningFourPounds()
{
    _returner.GiveChange(400);
    _mockCoinRelease.Verify(m => m.Release(200), Times.Exactly(2));
}
11 June 2011