Underused Moq Features

Underused Moq Features

Introduction

One of the most underused features of Moq, is its ability to handle callbacks and custom method implementations. While many developers are familiar with the basic setup and verification capabilities of Moq, the callback feature often goes underutilised. This feature can be incredibly powerful in certain testing scenarios.

You can find the official Moq documentation here https://documentation.help/Moq/.

Callbacks in Moq

The Callback method in Moq allows you to define an action that gets executed when a mocked method is called. This is particularly useful when you want to test how your code interacts with the mocked object, beyond simply verifying that methods were called.

Example Usage:

Suppose you have an interface IService with a method DoSomething that takes an integer argument. You can use the Callback method to capture the argument passed to DoSomething:

var mockService = new Mock<IService>();
int capturedArgument = 0;

mockService.Setup(service => service.DoSomething(It.IsAny<int>()))
           .Callback<int>(arg => capturedArgument = arg);

// Now, when DoSomething is called, capturedArgument will store its argument

Custom Method Implementations

Another underused feature is the ability to provide custom implementations for methods of mocked objects, using Returns with a lambda expression. This allows for a high degree of control over the behaviour of mocks, which can be useful for simulating complex scenarios that would be difficult to replicate with real objects.

Example Usage:

If you want DoSomething to return different values based on its input, you can set it up like this:

mockService.Setup(service => service.CalculateSomething(It.IsAny<int>()))
           .Returns<int>(arg => arg % 2 == 0 ? "Even" : "Odd");

In this example, CalculateSomething returns “Even” or “Odd” based on whether the input is an even or odd number.

Conclusion

While Moq is widely used for setting up and verifying expectations on mocked objects, its capabilities for callbacks and custom method implementations are often underutilised.

These features can greatly enhance the flexibility and power of your unit tests, allowing for more detailed interaction testing and behaviour simulation.

Understanding and using these features can lead to more comprehensive unit tests in your C# projects.

I have written other posts about unit testing here: – Using Moq to Verify your Logging is working, NUnit’s Coolest Feature – Data-Driven Tests, Asynchronous Testing with NUnit and C#.

Stephen

Hi, my name is Stephen Finchett. I have been a software engineer for over 30 years and worked on complex, business critical, multi-user systems for all of my career. For the last 15 years, I have been concentrating on web based solutions using the Microsoft Stack including ASP.Net, C#, TypeScript, SQL Server and running everything at scale within Kubernetes.