AutoFixture creates Anonymous Variables, but you’d probably like to know how it does it. This post explains how.
As we previously saw, the CreateAnonymous method can create a new instance of a type known to it only from its type parameter:
MyClass sut = fixture.CreateAnonymous<MyClass>();
AutoFixture was never compiled with any knowledge of the MyClass type, so it obviously uses Reflection to create the instance. That’s hardly surprising in itself.
In the case of MyClass, it has a default constructor, so creating an instance is as simple as it can be, but what happens if we instead ask for a more complex instance?
As an example, the ComplexParent type has this constructor:
public ComplexParent(ComplexChild child)
ComplexChild, however, has two constructors:
public ComplexChild(string name)
and
public ComplexChild(string name, int number)
So what happens when we ask AutoFixture to create an instance of ComplexParent?
ComplexParent only has a single public constructor, so AutoFixture doesn’t have any other choice than picking that. This means that it must now create an anonymous instance of ComplexChild.
Fortunately, AutoFixture’s raison d’être is creating objects, so creating an instance of ComplexChild isn’t a big deal; the only thing it needs to figure out is which constructor to pick. When multiple public constructors are available, it always picks the one with the fewest number of arguments – in this case ComplexChild(string).
Obviously, it then needs to create an anonymous string value. For primitive types like strings, numbers and booleans, AutoFixture has custom algorithms for value creation. Since I’ll cover those mechanisms later, suffice it to say that Constrained Non-Determinism is used to create an anonymous string.
At this point, AutoFixture has all the information it needs, and it can now return a properly initialized instance of ComplexParent.
This ability to create instances of almost arbitrarily complex types is a real time-saver: That, more than the ability to create single strings or numbers, was the reason I originally created AutoFixture, since I got tired of initializing complex object graphs just to satisfy some API that the Test Fixture requires.
It also has the additional advantage that it hides all the irrelevant object creation code that the Test Fixture needs, but which isn’t relevant for the test at hand.
Remember Me
a@href@title, b, em, i, strike, strong
Page rendered at Tuesday, February 07, 2012 5:57:24 PM (Romance Standard Time, UTC+01:00)
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.