Skip to content

FakeItEasy Cheat Sheet for Moq Users

I am currently learning the ins and outs of the FakeItEasy mocking framework. I know my way around Moq, a simple and easy to use framework for the same purpose. This cheat sheet has examples for the most common use cases and explains the differences to Moq.

Why use a mocking framework?

A mocking framework like Moq or FakeItEasy helps you to write unit tests faster. Instead of writing your own classes as stand-ins for your dependencies, you let the framework generate those mocks for you. This is especially helpful when you use dependency injection and want to test your class without the need for a database or web service.

Where to start?

Check the Quickstart for your first steps with FakeItEasy. One single page has all you need to start and you are already in the well-written documentation that answers your other questions.

Open your test project, right-click on References and select “Manage NuGet Packages...” to open the NuGet packages dialog. Search for FakeItEasy and install this package:

The NuGet Package of FakeItEasy is by Patrik Haegne

Alternatively, open the Package Manager Console and type

Install-Package FakeItEasy
 
The following examples use this interface and the minimalistic Job class:

public interface IExecuteWork
{
    bool IsRunning();
    int JobsQueued();
    DateTime StarTime();
    string CurrentUser();
    double MoneySpend();
    Job CurrentJob();
    void Add(Job job);
}

public class Job
{
    public int Id { get; set; }
}

No configuration required

To use FakeItEasy you just need to create a fake. As with Moq, you don’t need any configuration to get the default values of a value type back:

1
2
3
4
5
6
7
8
9
var mock = A.Fake<IExecuteWork>();

Assert.False(mock.IsRunning());
Assert.Equal(0, mock.JobsQueued());
Assert.Equal(DateTime.MinValue, mock.StarTime());
Assert.Equal(0d, mock.MoneySpend());

Assert.Equal(string.Empty, mock.CurrentUser());
Assert.Equal("JobProxy", mock.CurrentJob().GetType().Name);

The biggest difference to Moq is the handling of reference types. If you do not specify a value, then Moq returns NULL.
The behaviour of FakeItEasy is more user friendly: Whenever possible it creates a fake a dummy. That can be an empty string like in the call for CurrentUser() or a proxy as with CurrentJob(). It only returns NULL when the type can’t be overridden, or it isn't possible to create all the dummies for a non-default constructor. (For a more precise definition check the explanation by Blair Conrad in the comments section.)

Specify a return value

You only need to configure your mock when you need a specific return value for a method call. FakeItEasy has a powerful fluent interface that makes the configuration easy to read:

1
2
3
4
5
6
7
var mock = A.Fake<IExecuteWork>();
A.CallTo(() => mock.JobsQueued()).Returns(5);

Assert.Equal(5, mock.JobsQueued());

A.CallTo(() => mock.JobsQueued()).MustHaveHappenedOnceExactly();
A.CallTo(() => mock.CurrentUser()).MustNotHaveHappened();

You can use the same syntax from the configuration to verify that a method call occurred. That makes the memorisation a lot simpler than with Moq. Dedicated methods cover the most common verifications and should this not be enough, you can use MustHaveHappenedANumberOfTimesMatching() to set your own number of calls you expect.

Change return values between calls

When you need to mimic a more complex system that changes its state between calls, you can simply keep appending your configuration with those changed values:

var mock = A.Fake<IExecuteWork>();
A.CallTo(() => mock.IsRunning())
    .Returns(true).Once()
    .Then.Returns(false).NumberOfTimes(3)
    .Then.Returns(true);

Assert.True(mock.IsRunning());

Assert.False(mock.IsRunning());
Assert.False(mock.IsRunning());
Assert.False(mock.IsRunning());

Assert.True(mock.IsRunning());

Moq offers the same functionality with SetupSequence(), but in a less readable way for scenarios like the one above.

Get the argument of a method call

In some test scenarios is changing the return value not enough. FakeItEasy allows you to replace the method with your own code. With full access to the arguments used for the method call, you could catch them and check that the right things happen inside your system:

var jobs = new List<Job>();

var mock = A.Fake<IExecuteWork>();
A.CallTo(() => mock.Add(A<Job>._))
    .Invokes((Job x) => jobs.Add(x));

var job1 = new Job(){Id = 1};
var job2 = new Job() { Id = 2 };

mock.Add(job1);
mock.Add(job2);

Assert.Equal(2, jobs.Count);
Assert.Equal(1, jobs.First().Id);
Assert.Equal(2, jobs.Last().Id);

(In a realistic scenario the call to the Add() method would be inside your system under test.)

In Moq you can use Callback() method to get the same result.

Conclusion

FakeItEasy is an easy to use framework. As soon as you get used to the syntax you can work without any problems or surprises. I like the behaviour with reference values even more than in Moq. I don't change all my test code from Moq to FakeItEasy, but for new projects I will need to consider which mocking framework I should use.

Update on 18.2.2018: Use dummy instead of fake as the default behaviour with reference types