Search code examples
c#tddxunitautofixture

How to add a specific implementation of a Mock created with Autofixture?


I am writing tests for class (lets call it Sut) which has some dependencies injected via constructors. For this class I have to use the constructor with the most parameters, therefore I used the AutoMoqDataAttributeGreedy implementation:

public class AutoMoqDataAttribute : AutoDataAttribute
{
    public AutoMoqDataAttribute() : base(new Fixture().Customize(new AutoMoqCustomization()))
    {
    }
}

public class AutoMoqDataAttributeGreedy : AutoDataAttribute
{
    public AutoMoqDataAttributeGreedy() : base(new Fixture(new GreedyEngineParts()).Customize(new AutoMoqCustomization()))
    {
    }
}

The constructor of my sut looks like this:

public class Sut(IInerface1 interface1, IInterface2 interface2, IInterface3 interface3)
{
    Interface1 = interface1;
    Interface2 = interface2;
    Interface3 = interface3;
}

One example test looks like this:

[Theory, AutoMoqDataAttributeGreedy]
public void SomeTest([Frozen]Mock<IInterface1> mock1 ,
                      Mock<IInterface2> mock2, 
                      Sut sut, 
                      SomOtherdata data)
{
    // mock1 and mock2 Setup omitted

    // I want to avoid following line
    sut.AddSpeficicInterfaceImplementation(new IInterface3TestImplementation());

    sut.MethodIWantToTest();

    //Assert omitted 
}

The problem is that I need a specific implementation of IInterface3 for testing and I want to avoid adding a method to my SUT (Interface3TestImplementation) only for my unit test and I also I want to avoid repeating code since I have to add this instance in each and every test.

Is there a nice and neat way to have this implementation being added for all my test / for specific tests with Autofixture?


Solution

  • If you need to do this as a one-off test, then the answer by Enrico Campidoglio is the way to go.

    If you need this as a general rule throughout all of your unit tests, you can customize the Fixture with a TypeRelay:

    fixture.Customizations.Add(
        new TypeRelay(
            typeof(IInterface3),
            typeof(IInterface3TestImplementation));
    

    This will change fixture so that, whenever IInterface3 is needed, an instance of IInterface3TestImplementation will be created and used.