Better assertions when verifying Moq’d methods have been called

B

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 ICustomerService
The Save method returns an int, so we set our mocked method to return 1, when it is called with any Customer object.

Our unit test could look something like this:

This test will of course pass. But, if we make a small change in our CustomerController

Now our test will correctly fail.
However the exact reason for the failure isn’t clear:

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: