Problem
As part of the use of AutoFixture the Generic Create<>
methods and related functionality is really handy but sometimes you have a Type of an object you want to make and thats when generics start to be a bit painful. However help is at hand and there is a way to use AutoFixture to generate an instance for you.
Option 1
The first option feels a bit clunky but is fully workable.
You start off with an Fixture.
var fixture = new Fixture();
Now once you have the fixture instance you can use the none generic Create
method. The signature looks a little odd though as the method parameter is asking for an “object” but we’ve got a type. This threw me for a while but it is fine.
var instance = fixture.Create(ourType, new SpecimenContext(fixture));
This will give us an anonymous instance of the target type. It does look a little clunky though and there is another way.
Option 2
Again, you start with a Fixture instance and then this time use the SpecimenContext
directly passing in the fixture instance and use the Resolve
method. Using a method called Resolve
feels a bit more inline with using Types and reflection than Create
to me.
var instance = new SpecimenContext(fixture).Resolve(ourType);
Full Test Examples
Using the ProductId
record type I’ve used in previous posts about AutoFixture we can do the following.
[Fact]
public void With_None_Generic_1()
{
var fixture = new Fixture();
var instance = fixture.Create(typeof(ProductId), new SpecimenContext(fixture));
}
[Fact]
public void With_None_Generic_2()
{
var fixture = new Fixture();
var instance = new SpecimenContext(fixture).Resolve(typeof(ProductId));
}
Real World Usage
I had a requirement recently in a test where I wanted to test that certain types didn’t get processed on a certain condition. All the types implemented a specfic interface and I wanted to test each of the types. The first option I investigated was using the MemberData
to inject instances of each type into the test. However this would require creating my own instances of them and I wanted to use AutoFixture.
Using the methods we have discussed above I ended up writing some tests as below. The interface and implementations examples are to show the type of code structure I was working with.
public interface IDoStuff
{
}
public class DoStuffOne : IDoStuff
{
}
public class DoStuffTwo : IDoStuff
{
}
Using the above I was able to construct tests with a similar flow as to this.
[Theory]
[InlineData(typeof(DoStuffOne))]
[InlineData(typeof(DoStuffTwo))]
public void Usage(Type targetType)
{
// Arrange
var fixture = new Fixture();
var instance = new SpecimenContext(fixture).Resolve(targetType) as IDoStuff;
// Act
// Assert
}
Conclusion
In this post we have looked at how to use AutoFixture to generate anonymous data instances from a specified type instead of using the generic create methods.
AutoFixture is a great library for generating anonymous test data for unit tests. If you’ve not tried it yet then check it out!
Any questions/comments then please contact me on Twitter @WestDiscGolf