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.

Sunday, December 6, 2015

AutoFixture for the Win

"What have I kept back?"
-- Shakespeare, Antony and Cleopatra
Act V, Scene II, Line 147.2

Anyone who has paired with me while working in C# knows that I am addicted to AutoFixture.  Now I do not try to add it to everything that I am working, but usually it finds its way into whatever I am working on.  Why?  Simply put, using AutoFixture allows me to focus on the task at hand.

Here is a quick example:

In this example I am implementing the higher order function Map using the higher order function Fold (see my other post if this interested you).

What do you not see in the tests?  The setting up of the test data.

Why?  It is not important to the task at hand.  We do not need it to test the behavior of Map.  Map takes a collection and a function and applies the function against every member of the collection producing a new collection.  What we want to verify is the applies part, which only requires a collection and a function, the actual members of the collection (and the function) do not matter for this verification.

Staying focus on the task at hand is the power of a test fixture and having someone else implement the test fixture for you is even better.  Using AutoFixture with xUnit you really do not need to think about setting up test data at all and that is good thing.