---
title: Testing Your Factories First
teaser:
tags: web,open source,testing,factory_girl,factory_bot
author: Reade Harris
published_on: 2012-09-06
---

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

    class User < ActiveRecord::Base
      validates_presence_of :first_name
    end

And then had this happen?:

```bash
rake spec
```

![''](http://media.tumblr.com/tumblr_m9wdyr3GFs1rwqb7q.jpg)

If you're using [FactoryBot](https://github.com/thoughtbot/factory_bot)[^1], 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

    FactoryBot.define do
      factory :user do
        first_name { 'Jonah' }
      end
    end

But how do you save yourself the time (and potential heart attack) of watching
all those dreaded <span style="color: red; font-weight: bold;">F</span>s 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
      end
    end

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

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

Fancytime! Now all our factory specs are in one place, <abbr title="Don't Repeat
Yourself">DRY</abbr> 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'
      end
    end

    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:

```bash
rake spec
```

![''](http://media.tumblr.com/tumblr_m9we3ciGKS1rwqb7q.png)

No more panic attacks necessary.

![''](http://media.tumblr.com/tumblr_m9wf0f738J1rwqb7q.jpg)

Just one of the many new things I've learned in my first day as a [thoughtbot
apprentice](http://apprentice.io)!

[^1]: Looking for FactoryGirl? The library was renamed in 2017.
[Project name history can be found here.](https://github.com/thoughtbot/factory_bot/blob/master/NAME.md)
