/automoxture

Provides a base class to work with AutoFixture and AutoMoq

Primary LanguageC#MIT LicenseMIT

AutoMoxture

AutoMoxture provides a convenient base test class to work with AutoFixture and AutoMoq so you can inherit all your test classes from it.

Back-story

Consider you would like to write unit tests for this class :

public class ServiceWithDependencies
{
    private readonly IDependency1 dependency1;
    private readonly IDependency2 dependency2;
    private readonly IDependency3 dependency3;
    private readonly IDependency4 dependency4;
    private readonly IDependency5 dependency5;

    public ServiceWithDependencies(
        IDependency1 dependency1,
        IDependency2 dependency2,
        IDependency3 dependency3,
        IDependency3 dependency4,
        IDependency3 dependency5)
    {
        this.dependency1 = dependency1;
        this.dependency2 = dependency2;
        this.dependency3 = dependency3;
        this.dependency4 = dependency4;
        this.dependency5 = dependency5;
    }

    public string Concat(string prefix)
    {
        return prefix
            + this.dependency1.GetString()
            + this.dependency2.GetString()
            + this.dependency3.GetString()
            + this.dependency4.GetString()
            + this.dependency5.GetString();
    }
}

Without AutoMoxture, you would end up writing this at some point :

public class ServiceWithDependenciesTests
{
    ...

    // Arrange
    var mockDependency1 = new Mock<IDependency1>();
    var mockDependency2 = new Mock<IDependency2>();
    var mockDependency3 = new Mock<IDependency3>();
    var mockDependency4 = new Mock<IDependency4>();
    var mockDependency5 = new Mock<IDependency5>();
    var sut = new ServiceWithDependencies(
        mockDependency1.Object,
        mockDependency2.Object,
        mockDependency3.Object,
        mockDependency4.Object,
        mockDependency5.Object);
    
    ...
}

or this :

public class ServiceWithDependenciesTests
{
    private AutoFixture.Fixture Fixture { get; }

    ...

    // Arrange
    var mockDependency1 = this.Create<Mock<IDependency1>>();
    var mockDependency2 = this.Create<Mock<IDependency2>>();
    var mockDependency3 = this.Create<Mock<IDependency3>>();
    var mockDependency4 = this.Create<Mock<IDependency4>>();
    var mockDependency5 = this.Create<Mock<IDependency5>>();
    var sut = new ServiceWithDependencies(
        mockDependency1.Object,
        mockDependency2.Object,
        mockDependency3.Object,
        mockDependency4.Object,
        mockDependency5.Object);

    ...
}

It's quite boring to write and it gets even worse if your class have more dependencies.
Also, if you add and/or remove dependencies, it won't build anymore and you have to go fix your tests.

AutoMoxture

Turns out, AutoFixture and AutoMoq have already solved this problem :

var fixture = new AutoFixture.Fixture();
fixture.Customize(new AutoMoqCustomization());
var sut = fixture.Create<ServiceWithDependencies>();

That's more or less what AutoMoxture is doing in its base class so you won't have to write this boilerplate code anymore.

  1. Start by inheriting AutoMoxtureTest :

    public class ServiceWithDependenciesTests : AutoMoxtureTest<ServiceWithDependencies>
    {
    }
  2. AutoMoxture will create and expose the Sut property out of the box :

    public class ServiceWithDependenciesTests : AutoMoxtureTest<ServiceWithDependencies>
    {
        ...
    
        // Act
        var response = this.Sut.Concat(...);
    
        ...
    }
  3. AutoMoxture inherits AutoFixture so regular/usual AutoFixture methods are accessible :

    public class ServiceWithDependenciesTests : AutoMoxtureTest<ServiceWithDependencies>
    {
        ...
        
        // Arrange
        var prefix = this.Create<string>();
    
        // Act
        var response = this.Sut.Concat(prefix);
    
        ...
    }
  4. AutoMoxture also introduces an alias method Mock<T> to quickly freeze a Mock :

    public class ServiceWithDependenciesTests : AutoMoxtureTest<ServiceWithDependencies>
    {
        ...
    
        // Arrange
        var prefix = this.Create<string>();
    
        var dependentString = this.Create<string>();
        this.Mock<Dependency1>()
            .Setup(m => m.GetString())
            .Returns(dependentString);
    
        // Act
        var response = this.Sut.Concat(prefix);
    
        ...
    }
  5. Overall, the test might end up looking like this :

    public class ServiceWithDependenciesTests : AutoMoxtureTest<ServiceWithDependencies>
    {
        ...
    
        // Arrange
        var prefix = this.Create<string>();
    
        var dependentString = this.Create<string>();
        this.Mock<Dependency1>()
            .Setup(m => m.GetString())
            .Returns(dependentString);
    
        // Act
        var response = this.Sut.Concat(prefix);
    
        // Assert
        response.Should().Contain(dependentString);
    
        ...
    }

Customize the fixture

It is possible to customize the Fixture in your constructor.

public class ServiceWithDependenciesTests : AutoMoxtureTest
{
    public class ServiceWithDependenciesTests()
    {
        this.Customize<TheTypeToCustomize>(c => c.FromFactory(new MethodInvoker(new GreedyConstructorQuery())));
    }
}

This will apply to all the tests in the class.
If you don't want this behavior, call the Customize method directly inside your test method.

public class ServiceWithDependenciesTests : AutoMoxtureTest
{
    public void Test1()
    {
        this.Customize<TheTypeToCustomize>(c => c.FromFactory(new MethodInvoker(new GreedyConstructorQuery())));
    }
}

Customize the SUT factory

Sometimes you need to control the way the SUT is created. More likely, you may have a single test that needs a particular SUT setup. You can provide a new factory at any time like this:

// Do stuff with the old/regular SUT
var sutBeforeChange = this.Sut;

// Provide a new factory
this.SutFactory = () => new TheSutType();

// Do stuff with the new/latest SUT
var sutAfterChange = this.Sut;