Mocking – JustMock Lite, NSubstitute, FakeItEasy and Moq

I having been working on several projects with different teams, each have their preferred mocking framework (as well as many other differences in choices of tech.), this post is not meant as a comparison of popularity, preference or even functionality, its really more of a reminder to myself how to use each framework for the core mocking requirements so when switching between teams/projects I’ve a little reminder of the different syntax etc.

Note: This post is not complete or particularly comprehensive and I’ll update further as I need to use other features of the various libraries, but just wanted to get this published before I forget about it. Also there may be better or alternates ways to do things in different frameworks, for the purpose of this post I’m only really interested in showing the bare minimum changes to switch between frameworks.

Please note, MOQ version 4.20 has introduced a SponsoreLink which appears to send data to some third party. See discussions on GitHub.

What are we mocking?

Before we get into the details of the Mock frameworks, let’s see what we’re mocking

public interface IDataProvider
{
  IList<string> GetIds(string filter);
  event EventHandler Updates;
}

So let’s assume this will be an interface to some data provider, whether it’s remote or what the implementation is makes no difference, but the premise is we get some data using GetIds – maybe a list of trades in a trading application. The event tells us there have been updates to the data (this is a rather simplistic example as we don’t tell the consumer what the updates are, but you get the idea hopefully).

We’ll be passing the IDataProvider into a class which will act like a repository and will be used to get the data specific to that repository and the likes, the implementation of this is not really important to the specifics of this post and hence not included here.

Arrange, Act and Assert (AAA)

AAA is a pattern used within unit tests to

  • Arrange – initialize code including setting up any requirements for the system under test, i.e. create instances of objects to be tested, initialize values of the system under test etc.
  • Act – this is really just the action of using the code that we’re testing
  • Assert – this is the stage where we assert or verify results, i.e. did the system under test return the expected data/value

In terms of mocking frameworks, these should also follow and allow a similar flow when used. What we’re after is a way to create instances of

Arrange

To arrange our mock (or unit tests in general) we aim to create the component parts of a test and setup methods regarding what happens when they’re called etc.. In the case of using a mocking framework, we’ll use the framework to create instances of interfaces (or actual objects in some cases) and as the methods on an object don’t really have implementations behind them, we will want to declare what happens when code tries to call our mocked methods.

JustMock

var provider = Mock.Create<IDataProvider>();

Mock.Arrange(() => provider.GetData("/trades")).Returns(tradeData);

Moq

var provider = new Mock<IDataProvider>();
// or
var provider = Mock.Of<IDataProvider>();

provider.Setup(instance => 
   instance.GetTrades("/trades")).Returns(tradeData);

NSubstitute

var provider = Substitute.For<IDataProvider>();

provider.GetTrades("/trades").Returns(tradeData);

FakeItEasy

var provider = A.Fake<IDataProvider>();

A.CallTo(() => provider.GetTrades("/trades")).Returns(tradeData);

Act

The Act phase is actually the use of our mock objects as if we’re calling the actual implementation, hence in our code we may actually call

provider.GetTrades(route);

See also the section on events to see the mocking frameworks calling events.

Assert

In the unit tests we would now assert the results of our system under test, this may take a form such as of an NUnit assert, such as

Assert.AreEqual(3, systemUnderTest.Trades.Count);

This isn’t really part of the mock, as by this time hopefully our mock objects and methods have been called but we might wish to verify that the calls to the mocked methods actually happened.

Verify

In cases where you wish to assert that a mock has been called correctly, i.e. with the correct arguments or it’s been called N number of times, then we need to Assert. Assertions may be quick complex, for example we might want to ensure that a mock was only called with specific arguments, was called once or many times, maybe we don’t care about the arguments etc.

Let’s look at a fairly simple example where we want to ensure our mocked method is called once and once only

Note: JustMock includes the expectations of call occurrences etc. when arrange the mock hence we just verify or in JustMock, Assert, that all the previous Arrange definitions have been met.

JustMock

Mock.Assert(provider);

Moq

provider.Verify(instance => instance.GetTrades("/trades"), Times.Once());

NSubstitute

provider.Received(1).GetTrades("/trades").

FakeItEasy

A.CallTo(() => provider.GetTrades("/trades")).
   Returns(tradeData).MustHaveHappenedOnceExactly();

What about exceptions?

In some cases we want to mimic the mocked code throwing an exception, we do this as part of the Arrange phase on all frameworks

JustMock

Mock.Arrange(() => provider.GetIds("/trades"))
   .Throws<ArgumentNullException>();

Moq

provider.Setup(instance => instance.GetIds("/trades"))
   .Throws<ArgumentNullException>();

NSubstitute

provider.GetIds("/trades").Returns(x => throw new ArgumentNullException());

FakeItEasy

A.CallTo(() => provider.GetIds("/trades")).Throws<ArgumentNullException>();

What about events?

Ofcourse C# has an event model which we would also want to mock, let’s see how each framework allows us to simulate events. The Mock framework would already have supplied the event code and hence what we’re really wanting to do it cause an event to occur. This would therefore be part of the Act phase

JustMock

Mock.Raise(() => provider.Updates += null, null, null);

Moq

provider.Raise(instance => 
   instance.Updates += null, EventArgs.Empty);

NSubstitute

provider.Updates += Raise.Event();

FakeItEasy

provider.Updates += Raise.WithEmpty();

Code

Code is available on GitHub