Non-generic CreateAnonymous method for AutoFixture
I sometimes (not often) find myself needing a non-generic version of the CreateAnonymous extension-method for AutoFixture. Usually when needing a test value, you do something like this:
int someInt = new Fixture().CreateAnonymous<int>();
The code works for 99% of all tests. Now and then I write reflection based tests, testing conventions like:
- All methods start with a capital letter.
- All actions on ASP.NET MVC controllers specify either an HttpPost or HttpGet attribute.
- No public methods specify out parameters.
The above examples are all fictional and don’t represent tests I’ve actually written. The point is, tests assert the existing code base as well as the code added in the future.
These “self-extending” tests sometimes need test data for input arguments. I’ve simply loved AutoFixture from the second I started using it, which is why I always use this framework to build test data. The CreateAnonymous method takes a generic argument, which is hard to specify when not known at compile-time. In fact, the simplest possible example of doing this with AutoFixture would look something like this:
var fixture = new Fixture();
var buildMethod = typeof(Fixture).GetMethod("Build");
var buildGenericMethod = buildMethod.MakeGenericMethod(typeof(int));
var composer = buildGenericMethod.Invoke(fixture, new object[0]) as ISpecimenBuilderComposer;
var create = typeof(SpecimenFactory).GetMethods().Where(m => m.Name.Equals("CreateAnonymous")).ToList()[1];
var gen = create.MakeGenericMethod(type);
var instance = gen.Invoke(typeof(SpecimenFactory), new object[] { composer });
Ugly right? In exactly this case, a non-generic overload of CreateAnonymous would be fantastic for avoiding those nasty reflection-based code lines in your test-project. Unfortunately, Mark Seemann and Co. didn’t provide us with such an overload, but Mark was luckily a great help in finding a solution to the problem. A non-generic overload of CreateAnonymous can be written as a new extension method for Fixture as simply as this:
public static class AutoFixtureExtensions
{
public static object CreateAnonymous(this Fixture fixture, Type type)
{
var context = new SpecimenContext(fixture.Compose());
return context.Resolve(type);
}
}
This makes it possible to write a test containing code like this:
int someInt = new Fixture().CreateAnonymous(typeof(int));