There are quite a few different mocking libraries in .NET. Moq and NSubstitute seem to be by far the main ones I hear that developers use. I've used both of these in different projects, and really like them both. Whilst my preference leans towards NSubstitute, I'd be happy using either. Out of interest, I posted a Twitter poll to see what other people preferred, and the results and replies were really interesting!...
The winner of the poll is clear - but interestingly, a lot of the replies indicated that they used Moq just because it was the most well known / used, and they hadn't tried anything else. There was certainly a lot of love for NSubstitute in the replies, commenting that the API is much cleaner.
I thought it would be interesting to compare some of the leading libraries like for like. So I picked the top three in the poll - namely, Moq, NSubstitute, and FakeItEasy. And I'll go through some code snippets for some of the more common requirements of a mocking library. Note that I can't possibly cover every thing in this blog post, but I'll focus on the features I find myself mostly using.
But first, what does a mocking library actually do?...
What is a mocking library?
When writing a test, quite often you want to only test one particular class and method. But that method might call a dependency that calls into a database, or calls an external service. When writing an integration test, you may want to include those dependencies in your your test - perhaps using a real database span up in Docker, or an in-memory database. But what if you're only writing a unit-test (or the integration can't simulate a particular dependency)? How do you call the method you want to test, without it calling into the dependency and therefore making that database call?
Quite often in .NET codebases, you'll quite often see classes implement an interface - especially those which call into databases or make external API/service calls. For example, you might have a class called
EFStockChecker which has Entity Framework code that talks to a database to check stock level. This contains implementation details - ie. it uses the Entity Framework library. This might then implement an interface called
It is this interface that the rest of the codebase ideally should use - not the concrete type (implementation). The key point here is that the interface has no concept of Entity Framework, or whatever database technology we might be using. All it does is describe the intent. This is known as dependency inversion. When programming in this manor, your business logic isn't concerned with the implementation details of its dependencies. It also means that those dependences are really easy to replace with another implementation when testing.
Let's continue with the
bool IsProductInStock(string sku);
Nothing in the above interface indicates a database or database technology. It's just about the requirement, not how that requirement is fulfilled.
Then I might have some code in my business logic that does this...
public class OrderHandler
private readonly IStockChecker _stockChecker;
private readonly IOrderRepository _orderRepository;
public OrderHandler(IStockChecker stockChecker, IOrderRepository orderRepository)
_stockChecker = stockChecker;
_orderRepository = orderRepository;
public void ProcessOrder(string sku)
Because this code only knows about abstractions (ie. the interfaces), it's easy to run this code without using the production implementation of those interfaces. I could just create another implementations just for the test that implements those interfaces, but doesn't call the database. These test implementations are known as 'stubs'.
A mocking library allows you to simulate an interface or abstract type's implementation. You instantiate a 'mock' object of the interface, and tell that mock object what it should return if a method/property is called against that mock. You can also assert that a method/property was or wasn't called.
Some people prefer sticking to stubs over mocking libraries, but I personally prefer to avoid creating additional classes when a mocking library can do it for us. A mocking library also adds additional functionality, like as mentioned above - being able to assert/verify that a mocked method was called. You could obviously implement this yourself in your test implementation - but a mocking library can do this for you, so why reinvent the wheel?
The basic scenario we'll be using as an example
Let's start with a very simple scenario. Imagine we're testing the above-mentioned
ProcessOrder method. Two interfaces are injected into the constructor. The implementation of both of them call out into a database or API (but we don't care about the data source or implementation), as we're not testing this. We only care about the logic in our
ProcessOrder method. Eg. How does our
ProcessOrder handle the having stock vs being out of stock.
Below is an example test to ensure that an order isn't created if there's not enough stock (using the Moq mocking library)...
public void GivenInsufficientStock_DoNotCreateOrder()
var mockStockChecker = new Mock<IStockChecker>();
var mockOrderRepository = new Mock<IOrderRepository>();
mockStockChecker.Setup(x => x.IsProductInStock()).Returns(false);
var sut = new OrderHandler(mockStockChecker.Object, mockOrderRepository.Object);
mockOrderRepository.Verify(x => x.CreateOrder(It.IsAny<int>()), Times.Never);
As you can see, the dependencies are mocked out. The real implementation would have called out to a database, but the class we're testing doesn't know or care about this - it just cares that whatever "IsProductInStock" is, we get a boolean back. It doesn't care where that comes from, as that's not it's responsibility. What is it's responsibility is that if
IsProductInStock returns true, the class we're testing will execute
ProcessOrder. And likewise, if it returns false, it does not execute
The above example shows how simple it is to tell the mock object to return
IsProductInStock is called. This bit is just like a stub, but created for you by the mocking library.
You can also see how we can leverage the mock to verify that
CreateOrder was or wasn't called. This bit is like a 'spy', but again, done for you by the mocking library.
(for a description of the different types of test-doubles - eg. dummies, fakes, stubs, spies, mocks - Martin Fowler has a post with a short description of each).
In fact, on the NSubstitute homepage, they even try to move away from these specific definitions, and state: "Mock, stub, fake, spy, test double? Strict or loose? Nah, just substitute for the type you need!".
Comparing Mocking library syntax
Okay, now we know what a mocking library does - let's move onto some syntax comparisons...
Mock creation and simple 'Returns' Setup with no parameters
Let's start with how we create a mock, then declare a return value for a method or property in a mocked object...
var mockStockChecker = new Mock<IStockChecker>();
mockStockChecker.Setup(x => x.IsProductInStock()).Returns(true);
var sut = new TheClassIAmTesting(mockStockChecker.Object);
var mockStockChecker = Substitute.For<IStockChecker>();
var sut = new TheClassIAmTesting(mockStockChecker);
var mockStockChecker = A.Fake<IStockChecker>();
A.CallTo(() => mockStockChecker.IsProductInStock("")).Returns(true);
var sut = new TheClassIAmTesting(mockStockChecker);
NSubstitute certainly seems the cleanest here, not requiring
.Object or a
.Setup call and lambda. Note that Moq also has another syntax, where you don't need to use
.Object to get at the mocked object, but if you do this - you have the inverse problem, where you have to do
Mock.Get(myMock) to do any setup.
Moving forward, I'll omit the mock instantiation and the SUT call for brevity.
'Return' Setup with explicit parameters
What about if your method takes parameters? Eg, we know our
IsProductInStock method does take a 'sku' parameter...
mockStockChecker.Setup(x => x.IsProductInStock("banana")).Returns(false);
A.CallTo(() => mockStockChecker.IsProductInStock("orange")).Returns(true);
This is very similar to the previous example - you just specify the parameter value when setting it up.
'Return' Setup regardless of parameter values
And what if your method takes a parameter, but you don't care what values are passed to it by the code you're testing?...
mockStockChecker.Setup(x => x.IsProductInStock(It.IsAny<string>())).Returns(true);
// Or NSubstitute can also do this to specify that all arguments can be ignored
A.CallTo(() => mockStockChecker.IsProductInStock(A<string>.Ignored))).Returns(true);
They all have similar syntax here. Moq uses
It.IsAny<>() syntax, NSubstitute uses
Arg.Any<>(), and FakeItEasy uses
A<string>.Ignored. In NSubstitute, you can also use
ReturnsForAnyArgs and the parameters will be ignored. In the above example, I've used the
default keyword when doing this to make it more clear that these values are ignored - I could have put "", or any other value, but I think using
default makes it more clear.
Quite often you want to have tests testing how your code handles a dependency throwing an exception. Mocks allow you to simulate exceptions being thrown...
mockStockChecker.Setup(x => x.IsProductInStockAsync("")).Throws(new NullReferenceException());
A.CallTo(() => mockStockChecker.IsProductInStock("").Throws(new NullReferenceException());
All of these are very similar to their
Returns counterpart. Just replacing
Verifying a mocked method is or isn't called
Another really useful feature of mocking libraries is that you can spy on whether a mocked method was called or not. We saw an example of this in the
GivenInsufficientStock_DoNotCreateOrder code snippet earlier in this post, where we verified that
CreateOrder wasn't called when there was insufficient stock.
mockOrderRepository.Verify(x => x.CreateOrder()); // Defaults to Times.AtLeastOnce
mockOrderRepository.Verify(x => x.CreateOrder(), Times.Never);
mockOrderRepository.Verify(x => x.CreateOrder(), Times.Once);
mockOrderRepository.Verify(x => x.CreateOrder(), Times.Exactly(2));
mockOrderRepository.Verify(x => x.CreateOrder(), Times.Exactly(3));
A.CallTo(() => mockOrderRepository.CreateOrder()).MustHaveHappened();
A.CallTo(() => mockOrderRepository.CreateOrder()).MustNotHaveHappened();
A.CallTo(() => mockOrderRepository.CreateOrder()).MustHaveHappenedOnceExactly();
A.CallTo(() => mockOrderRepository.CreateOrder()).MustHaveHappenedTwiceExactly();
A.CallTo(() => mockOrderRepository.CreateOrder()).MustHaveHappened(3, Times.Exactly);
I've included a few examples above showing how to check for different numbers of calls to a mocked method. This particular method I've verifying has no parameters, but all the libraries support verifying the a call was made with specific parameter values, or any parameter values.
I certainly haven't touched on all the functionalities that exist in mocking libraries - but rather focused on the features I tend to mostly use. There is plenty of other functionality - eg. working with events, verifying the order of method calls, etc, etc. If there are any comparisons or examples you feel really belong in this post, please do let me know.
The aim of this post isn't to say one library is better than another, as when it comes down to it, they all pretty much do the same thing. The purpose of this post is just to provide a side-by-side comparison of some of the syntax, to hopefully give the you a feel of what mock creation and setup looks like across these different libraries.