Sunday, December 13, 2015

Round and Round We Go OR How to Stop Circular References in AutoFixture

"That many things, having full reference"
-- Shakespeare, Henry V
Act I, Scene II, Line 205

I love to use AutoFixture to setup the the arrange part of my tests.  I find that working without worrying about the arrange allows me to focus more on the task at hand.  A possible downside of working this way is that AutoFixture is mindlessly setting up all the test data.

Having AutoFixture setup your test data is fine when working with green field classes but when working with legacy code and third party code you getting into cases in which you have circular references.  What do I mean?  Compare the following:

Case 1:

class A has members with type B
type B has member with type C
type C is a primitive

Case 2:

class X has members with type Y
type Y has member with type Z
type Z has member with type X

In case 1 we have a termination point with type C, AutoFixture can happily go about and create an instance of A and populate all the members in the hierarchy with data.

In case 2 we do not have a termination point, Z has a member of type X which a member of type Y which a member of type Z which goes back to X and so on.  Case 2 has a circular reference and AutoFixture is unable to give us back an instance of X without going into an endless loop.  Luckily AutoFixture is smart enough to figure out that it is in an endless loop and will error out telling us about the issue.

What do we do if we have a class like X in legacy code or third party code?  We'll we can tell AutoFixture that we will have classes like X but that it is fine to just terminate the repeating hierarchy with a null or empty.  We use the following to do that:

I normally put this in my TestInitialize for the test class of the offender, but I can see putting in the arrange of a test class if you are mixing old and new.  There you have it, a way to use AutoFixture with dirty old classes.