Testing Your Factories First

Testing Your Factories First

Have you ever added a seemingly innocent validation to a model, like so:

class User < ActiveRecord::Base
  validates_presence_of :first_name

And then had this happen?:

$ rake spec

If you’re using FactoryGirl, this can often happen because you haven’t updated your factory to respect the new validation.

Of course, the fix is simple:

# spec/factories.rb

FactoryGirl.define do
  factory :user do
    first_name 'Jonah'

But how do you save yourself the time (and potential heart attack) of watching all those dreaded Fs go by?

Watching Over Your Factories

My old solution used to be adding a boilerplate test in each model’s unit spec, like so:

# spec/models/user_spec.rb

describe User do
  it 'has a valid Factory' do
    build(:user).should be_valid

This is better than nothing, but it has two major problems.

  • It’s not DRY. This code needs to be added to every unit spec.
  • It’s slow. The whole model spec (and potentially many other specs) will have to run before we can address the failure.

Enter our savior, the factories_spec.rb:>

 # spec/factories_spec.rb

FactoryGirl.factories.map(&:name).each do |factory_name|
  describe "The #{factory_name} factory" do
     it 'is valid' do
      build(factory_name).should be_valid

Fancytime! Now all our factory specs are in one place, DRY as a desert.

Fast-Failing Factories

On to the second problem: we don’t want to wait for all our specs to run to deal with this error.

If you use rake to run your tests, one way to take care of this is by adding a pre-requisite to your rake spec task:

# Rakefile

if defined?(RSpec)
  desc 'Run factory specs.'
  RSpec::Core::RakeTask.new(:factory_specs) do |t|
    t.pattern = './spec/factories_spec.rb'

task spec: :factory_specs

Now the :factory_specs task will need to run and succeed before the whole suite is run. If you have a bad factory, you’ll know right away with a nice failure message:

$ rake spec

No more panic attacks necessary.

Just one of the many new things I’ve learned in my first day as a thoughtbot apprentice!

Reade Harris Developer

Hound reviews Ruby and CoffeeScript code for style violations and comments on your GitHub pull requests. Free for open source repos.