unit-testing Test Doubles Using a mocking framework to validate behaviour


Mocks are used when it is necessary to verify the interactions between the system under test and test doubles. Care needs to be taken to avoid creating overly brittle tests, but mocking can be particularly useful when the method to test is simply orchestrating other calls.

This test verifies that when the method under test is called (ProcessRecord), that the service method (UseValue) is called for the Record where Flag==true. To do this, it sets up a stub with canned data:

var stub = new Mock<IRecordProvider>();
stub.Setup(provider => provider.GetRecords()).Returns(new List<Record> {
    new Record { Id = 1, Flag=false, Value="First" },
    new Record { Id = 2, Flag=true, Value="Second" },
    new Record { Id = 3, Flag=false, Value="Third" }

Then it sets up a mock which implements the IService interface:

var mockService = new Mock<IService>();
mockService.Setup(service => service.UseValue(It.IsAny<string>())).Returns(true);

These are then supplied to the system under test and the method to be tested is called.

var sut = new SystemUnderTest(mockService.Object);

var processed = sut.ProcessRecord(stub.Object);

The mock can then be interrogated to verify that the expected call has been made to it. In this case, a call to UseValue, with one parameter "Second", which is the value from the record where Flag==true.

mockService.Verify(service => service.UseValue("Second"));