Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

Start small and compose: A strategy for using FactoryGirl

While I’m still not entirely sold on FactoryGirl, I often see it being used in a particularly lazy way. Imagine your basic factory:

factory :project

Before long you’re adding relations to projects, and the first thing people do is this:

factory :project do
  association :user

This immediately means that every single time you instantiate a project, you’re getting a user as well. In most cases this is more than you want, and if you continue to follow down this path you end up with a huge slow test suite. I prefer a slightly different strategy: start small and compose.

factory :project do

trait :with_manager do
  association :user, factory: :manager

This defines a very simple factory :project which gives you only a project and allows you to build a project with an associated user like so:

FactoryGirl.create(:project, :with_manager)

The result is a couple more arguments when you use the factory, but the overall code is more intention revealing.

If this is too much, you could always create a more descriptive factory:

factory :managed_project, parent: :project, traits: [:with_manager]

If you stick with this strategy, you’ll find that tests are more concise, factories are more useful and your test suite run time won’t grow as fast.

  1. Aaron says:

    Nice and succinct article. I think factories are another hammer and nail thing and they’re definitely a great solution to some problems and a terrible solution to others.

    I definitely in favour of this method of extending factories with what you require, it just makes your tests more readable.

    Some of our guys like to have factories that do a lot of work for you. Personally I’m in favour of explicit tests where you do all the work so it’s visible documentation of behaviour, rather than hidden documentation in your factories.


Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *