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?
AutoFixture is a library that you can use alongside your testing framework to reduce the amount of boilerplate test code you need to write and thus improve your productivity. At its core, AutoFixture helps you setup your tests by generating anonymous test data for you.
AutoFixture is an open source library for . NET designed to minimize the 'Arrange' phase of your unit tests in order to maximize maintainability.
AutoFixture is a tool designed to make Test-Driven Development more productive and unit tests more refactoring-safe.
The AutoMoqCustomization is the core of the integration of AutoFixture with Moq. By adding an instance of this class to the fixture, requests for non-concrete types will be handled by Moq. var fixture = new Fixture();
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.
Using your IFixture that you have created, you can call .Register against a specific interface and supply the object to use when that interface is then subsequently used.
e.g.
_fixture = new Fixture().Customize(new AutoMoqCustomization());
_fixture.Register<Interface3>(() => yourConcreteImplementation);
You could also use mocking that would allow you to then use .Freeze on the fixture and that way you could just set some expected calls against the interface and wouldn't need a completely concrete instance. You could let AutoFixture create a default implementation for you and apply the setup that you configured.
e.g.
var mockedInterface = _fixture.Freeze<Mock<Interface3>>();
mockedInterface
.Setup(x => x.PropertyOnInterface)
.Returns("some value");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With