Moq, according to its GitHub page, is “The most popular and friendly mocking framework for .NET”.
Mocking frameworks allow you to create a ‘fake’ version of a dependency (typically an interface, or abstract class).
With this fake, you can then instruct the methods return values, or invoke behaviour.
Alternatively you can assert the methods were called, with a certain set of parameters.
How we verify these methods were called can affect the maintainability of our tests.
Let’s suppose we have this interface.
Which is a dependency of the class we’re testing:
Our method takes a firstName and lastName and creates a
Customer object using those parameters.
It then passes that
Customer object to the
Save method on the injected ICustomerService.
For the purposes of our test, we inject a mocked
Save method returns an int, so we set our mocked method to return 1, when it is called with any
Our unit test could look something like this:
This test will of course pass. But, if we make a small change in our
Now our test will correctly fail.
However the exact reason for the failure isn’t clear:
Expected invocation on the mock at least once, but was never performed:
x => x.Save(It.Is(c => c.FirstName == "Alex" && c.LastName == "Brown"))
All this tells us is that we didn’t call our dependency with an object that matches. It doesn’t give any indication as to why that object didn’t match.
Moq has a
Callback function which we can use to assign our mocked
ICustomerService.Save method to a variable outside of our setup.
Later on, we can use this variable for assertions.
And now, we can individually assert on each parameter:
If we run this test (without fixing our code from the previous failure) it now gives a much clearer failure:
Expected string length 5 but was 4. Strings differ at index 0.
But was: "Alex"