Autofixture and Moq to test Entity Framework project

In the past month I have been using brilliant tool from Mark Seemann called Autofixture. The tool is aiming unit tests and shall help you create objects with some data filled in.

Usually for unit tests you need to create your objects manually and give them some kind of data inside of the objects, so you don’t get NullReferenceExceptions. And that sometimes takes a while and not always pleasant:

        var person = new Person
        {
            FirstName = "Dilbert",
            MiddleName = "Wall-E",
            Surname = "Smith",
            KnownAs = "Pointy Haired Boss",
            DateOfBirth = new DateTime(1975, 12, 31),
            Gender = Gender.Male,
            MaritalStatus = MaritalStatus.Single,
        };

You can use builder pattern and re-use the builder every time you need an instance of Person.

var person = new PersonBuilder().WithSurname("Martin").Build();

That is more DRY and much more readable. Also to the test reader it is much more clear what are your intentions in the test and what is important for the test.

The problem comes when you have hundreds of models that all have to have builder classes. But AutoFixture relieves you from writing builders:

var fixture = new Fixture();
var person = fixture.Build<Person>().With(p => p.Surname, "Martin").Create<Person>();

Intent is clear, it is readable and you don’t have to write any builders. Autofixture will fill in all the properties and public fields for you. Strings by default are filled in with GUIDs, numbers are random. All the properties that are classes are also created for you and fill in with “junk” data. Autofixture walks down your model chain and creates objects for you, so you won’t see a NullReferenceException coming from your model ever again. This is just magic!

One thing that Autofixture allowed me to do is to replace Integration Tests with Unit Tests. I just did not need to go to database to test my service classes. Combination of Autofixture and Moq is just wonderful. Moq allowed me to mock out repositories and Autofixture return a descent set of data from mocks.

Say I have a repository like this:

public class PersonRepository : IPersonRepository
{
    private readonly MyContext context;
    public PersonRepository(MyContext context)
    {
        this.context = context;
    }

    public IEnumerable<Person> All
    {
        get { return context.People.AsEnumerable(); }
    }
    public Person Find(int id)
    {
        return context.People.Find(id);
    }
    // other methods
}

In my tests I can fake out repository by Moq manually:

var repository = new Mock<IPersonRepository>();

Or I can use Autofixture MoqCustomisation, where Autofixture replaces objects with fake objects where it can:

var repository = fixture.Create<Mock<IPersonRepository>>();

This just creates an instance of the faked out repository. If you are working with just a repository, this is good enough. But usually you want to test a service class that uses a repository as a dependency:

public class MyService
{
    private readonly IPersonRepository personRepository;

    public MyService(IPersonRepository personRepository)
    {
        this.personRepository = personRepository;
    }

    public Person FindById(int id)
    {
        return personRepository.Find(id);
    }

    public IEnumerable<Person> AllPeople()
    {
        return personRepository.All;
    }
}

For that case you need to create an instance of the MyService class and give it faked repository:

var repository = new Mock<IPersonRepository>();
var sut = new MyService(repository.Object);

Problem with this approach is maintainability. What if you have 5 dependencies in your service class? You’ll have to create fakes for all the dependencies. What if you refactor your class and kill(or add) some of the dependencies? In this case your tests won’t compile until you add another dependency into the constructor.

Autofixture can work as automocking container and create all the mocks for you automatically:

var fixture = new Fixture().Customize(new AutoMoqCustomization());
var sut = fixture.Crate<MyService>();

Magic! This way your service got all the dependencies as fakes. Just magic, I’m telling you!

Next step in unit tests is to verify actions and usually you want to verify against your dependencies. With the snippet above you don’t get access to any of the fake objects. Now Freeze<>() comes to help from Autofixture.

var fixture = new Fixture().Customize(new AutoMoqCustomization());
var repository = fixture.Freeze<Mock<IPersonRepository>>();
var sut = fixture.Crate<MyService>();

Freeze<>() basically creates an instance of an object and keeps it in memory. And every time Autofixture needs another object of this type, it uses pre-created instance of the object. This way you get a handle of the faked object that is injected into your service. And can verify against it when you need it. Although be aware that you must freeze the object before you create your systems under test, otherwise injected fake won’t be the same as your handle.

Next step is to actually do some tests:

    [Test]
    public void FindById_GivenId_PersonObjectIsReturned()
    {
        //Arrange
        var fixture = new Fixture().Customize(new AutoMoqCustomization());
        var repostory = fixture.Freeze<Mock<IPersonRepository>>();
        repostory.Setup(r => r.Find(It.IsAny<int>())).Returns(fixture.Create<Person>());

        var sut = fixture.Create<MyService>();

        // Act
        var result = sut.FindById(fixture.Create<int>());

        // Assert
        Assert.NotNull(result);
    }

Here we set up an instance of fake repository, give it a setup, saying on Find() with any parameter of type int, return a person object that is created by Autofixture. Then we execute the method under test and verify that something was returned from it.

And another example:

    [Test]
    public void AllPeople_ReturnsCollectionOfPeople()
    {
        //Arrange
        var fixture = new Fixture().Customize(new AutoMoqCustomization());
        var repostory = fixture.Freeze<Mock<IPersonRepository>>();
        repostory.Setup(r => r.All).Returns(fixture.CreateMany<Person>());

        var sut = fixture.Create<MyService>();

        // Act
        var result = sut.AllPeople();

        // Assert
        Assert.IsNotEmpty(result);
    }

Here we set up repository to return a collection of People objects when asked for AllPeople(). Notice how I’m using fixture.CreateMany<People>() to create the collection of dummy data. By default Autofixture will give you 3 objects in the collection, but you can specify any number you like as a parameter: fixture.CreateMany<People>(42). Test assertion don’t really assert anything here, but I’m not really testing anything – just writing examples.

This is all for today. Next time I’ll talk about performance hit on your tests from Autofixture and how to deal with that.