Building FactoryGirl.NET

factory_girl.jpgAs some of you might have noticed, I’ve been talking about Ruby and Ruby on Rails more recently. It’s often good to get outside your comfort zone and see how other (web) developers live. One of the areas where Ruby really excels is the wealth of innovative testing/spec’ing libraries available. When writing tests/specs, we need objects to play with. Ruby has a variety of options in this regard, but I particularly like the factory approach espoused by gems such as factory_girl or machinist. I’m partial to factory_girl. So let’s take a look at the syntax and see if we can create something similar for .NET. First off, let’s take a look at the usage syntax:

describe Site do
  it "should register a new user" do
    user = FactoryGirl.build(:user)
    site = Site.new
    site.register(user)
    site.users.should include(user)
  end
end

If we want to customize the instance, we can do that too by passing in a hash as the second argument:

describe Site do
  it "should not register new admin users" do
    user = FactoryGirl.build(:user, :admin => true)
    site = Site.new
    site.register(user)
    site.should_not include(user)
  end
end

What is interesting about factory_girl is that we can create instances of objects without the visual clutter of irrelevant properties. A user requires a first and last name, but in the above cases, we don’t care what they are. In the second case, we can see that the user being an admin is important for this test/spec. By removing the irrelevant properties, we can quickly see at a glance the data that matters for this spec. We also have the advantage that as properties are added to the User class, we have one place to update them (e.g. in the factory_girl definition) and we don’t have to wade back through all our tests adding values for required properties.

ASIDE: Now you might be tempted to say that we’ve been doing something like this in .NET with the Object Mother pattern. The Object Mother pattern is a factory of sorts. The problem is that it tends to be a dumping ground for different variations of the test objects. For example, ObjectMother.CreateUser(), ObjectMother.CreateAdminUser(), ObjectMother.CreateUserWithFirstName(string firstName), ObjectMother.CreateAdminUserWithFirstName(string firstName). The result is a tightly-coupled big ball of testing mud where the team is loathe to re-use ObjectMother methods for fear of breaking other tests. So you end up with this sprawling mass of methods for creating test data, which is separated from the tests themselves. Not a good place to be in.

Let’s look at the syntax for defining our factories in factory_girl:

FactoryGirl.define do
  factory :user do
    first_name 'John'
    last_name  'Doe'
    admin      false
  end
end

There is a lot more to factory_girl than I’ve covered above. When defining factories, you can create associations, lazy attributes, aliases, sequences, callbacks, and much more to keep your factories clean, lean, and mean. When using the factories, there is more than just FactoryGirl.build. There is also FactoryGirl.create, which saves the built instance to the database, FactoryGirl.attributes_for, which provides you with a hash of values often useful for testing Controller create actions, and FactoryGirl.build_stubbed, which returns a stubbed out instance. Here we’re going to focus on FactoryGirl.build to see how close we can get to the Ruby syntax, but written in C#.

Let’s start by looking at what our definition syntax could look like in C#.


FactoryGirl.Define(() => new User());

We give FactoryGirl a Func that creates an instance of the object. Note the use of C# type inferencing so that we don’t have to specify the generic method argument on FactoryGirl.Define.


public static class FactoryGirl {
  private static readonly IDictionary<Type, Func> builders = new Dictinonary<Type, Func>();

  public static void Define(Func builder) {
    if(builders.ContainsKey(typeof(T))) throw new DuplicateFactoryException();
    builders.Add(typeof(T), () => builder());
  }
}

Basically I’m just keeping a hash table of Type versus Func. That way when I get asked to build an object later, I can look it up and run the Func. I have to play some games with the C# type system. My hash table has to store Func because the generic parameter is declared on the methods, not the class. C# is also not able to implicitly convert Func to Func. So I have to add a lambda to the hash table that calls the builder rather than adding the builder directly.


builders.Add(typeof(T), builder); // Compiler error

Whereas the following makes the C# compiler happy.


builders.Add(typeof(T), () => builder()); // Compiler is happy

Now let’s look at the API for building an object.


var user = FactoryGirl.Build();

From an implementation standpoint, we simply need to find the appropriate Func and execute it.

public static class FactoryGirl {
  public static T Build() {
    return (T) builders[typeof(T)];
  }
}

Simple enough. Now if we want to customize the object built…


var admin = FactoryGirl.Build(x => x.Admin = true);

We really just need to accept an Action, which we will execute after the object is constructed.

public static class FactoryGirl {
  public static T Build(Action overrides) {
    var result = (T) builders[typeof(T)];
    overrides(result);
    return result;
  }
}

With this simple implementation, we now have a central place to define our factories and build objects. Any customizations required are in the tests/specs themselves making it easier to understand our intentions in the tests/specs. When we add a new required property, we need to simply update our factory definition with an appropriate default. If needed, you can easily call FactoryGirl.Build() from within a factory definition. I have used this FactoryGirl technique in a production application and it dramatically cleaned up our specification code as compared to a previous project that used Object Mother. I hope it gives you some ideas of how to clean up your own test/spec code. If you are curious about the code or interested in extending FactoryGirl.NET to add some missing capabilities, such as Create, AttributesFor, BuildStubbed, or anything else, you can find the code on GitHub.com here.

UPDATE: A few people have asked me about customizing multiple properties when building an object. FactoryGirl.NET already supports this using the following syntax:

var user = FactoryGirl.Build(x => {
                x.Admin = true;
                x.Age = 42;
           });

About James Kovacs

James Kovacs is a Technical Evangelist for JetBrains. He is passionate in sharing his knowledge about OO, SOLID, TDD/BDD, testing, object-relational mapping, dependency injection, refactoring, continuous integration, and related techniques. He blogs on CodeBetter.com as well as his own blog, is a technical contributor for Pluralsight, writes articles for MSDN Magazine and CoDe Magazine, and is a frequent speaker at conferences and user groups. He is the creator of psake, a PowerShell-based build automation tool, intended to save developers from XML Hell. James is the Ruby Track Chair for DevTeach, one of Canada’s largest independent developer conferences. He received his Bachelors degree from the University of Toronto and his Masters degree from Harvard University.
This entry was posted in .NET. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://jameskovacs.com James Kovacs

    Good point about type-safety and immutable objects. I don’t plan to add it personally. One thing I wasn’t clear about was the intent of my article. It wasn’t to create a brand spanking new FactoryGirl for .NET, but to show people techniques for building their own tools. Using off-the-shelf object factories, mocking frameworks, testing harnesses, and other tools is part of being a software developer, but so is scratching your own itch and building something custom for your project. Sometimes you don’t need a whole framework, but some clever helper methods/classes to tidy up your code.

  • http://profiles.google.com/talktopete Pete Weissbrod

    Because it’s 90% syntax sugar that solves the same problem as AutoPoco, and neither this nor autopoco grow nicely with the breadth of your domain. This is a problem I have been looking to solve for awhile but havent found very good answers

  • http://nevercertain.com James Brechtel

    Hi James,

    I wrote a similar project a while ago called Plant ( https://github.com/jbrechtel/plant ).  I had very similar goals, specifically bringing FactoryGirl-like functionality to .NET.  One thing I struggled with was an approach that allowed for immutable objects and being type safe at the same time.  The examples I see here won’t work for immutable objects/constructor injection, do you plan on adding that?

    Currently Plant supports both but you only get type safety of your models when the object is mutable.  Though with Plant you end up having to create a wasted instance of an object to provide the property overrides.  I like how your approach uses an Action instead.  

    So far, my ideas for adding type-safety with immutable objects all have tradeoffs that I don’t like.  

  • http://jameskovacs.com James Kovacs

     No problem. Thanks for the tip, even if a dup.

  • http://twitter.com/chr_horsdal Christian Horsdal

    sorry for the duplicate – didn’t see that Autofixture was already mentioned.

  • http://twitter.com/chr_horsdal Christian Horsdal

    Not that it is exactly the same, but are you aware of AutoFixture (
    http://autofixture.codeplex.com/)?

  • Uladzimir Palkhouski

    NBuilder is another factory implementation that works well even when we have to deal with data persistance (nbuilder.org)

  • http://jameskovacs.com James Kovacs

    Dynamic might be useful for implementing FactoryGirl.BuildStubbed(). I’ll have to think about it…

  • http://jameskovacs.com James Kovacs

     I should have provided an example. FactoryGirl.Build takes an Action. So you can (and often do) pass it something like this:

    FactoryGirl.Build(x => {
                                                               x.Admin = true;
                                                               x.Age = 55;
                                                  });

  • http://jameskovacs.com James Kovacs

     Could you elaborate? Why the :(?

  • http://jameskovacs.com James Kovacs

    AutoFixture is more about test data generation with a bit of
    a factory mixed in. Personally I prefer something akin to Ruby’s faker
    gem (http://faker.rubyforge.org/), which generates more  realistic looking data and is often used in concert with factory_girl or machinist.

  • Anonymous

    Doesn’t this overlap with AutoFixture?

  • http://profiles.google.com/talktopete Pete Weissbrod

    at first I was like :D but then I was like :(

  • Anonymous

    Thinking out loud – I was wondering whether you could do something using dynamics.
    I came across this recently while trying to mock the Add method on the EF database context. You could have a hash of objects by type but let the type be set at runtime.
    Not used dynamic too much yet, so not sure if that makes any sense…

  • Jose Cardenas

    What  if I want to to so something like FactoryGirl.Build(x => x.Admin = true and x.age = 55) ???

  • Jose Cardenas

    Thanks for sharing, this is awesome stuff !!