---
title: Waiting For a Factory~~Girl~~Bot
teaser: Introducing a gem to create test data via factories.
tags: news,ruby,testing,factory_girl,factory_bot
author: Joe Ferris
published_on: 2008-06-06
---

## I Can't Get No Satisfaction (From Fixtures)

Here at thoughtbot, we've had it with fixtures. Is Susie an admin? Which user
owns the Exciting Test post? Are there any categories without posts, or should I
add that fixture for this test? How did this post end up in the future? Do you
like asking these questions when writing tests? I don't.

I also don't like tests that don't tell you anything about the context you're
testing:

```ruby
should "find recently updated posts" do
  assert_equal posts(:lions_attack), Post.most_recent
end
```

One method in one model being tested, and three files to look through to
understand it. I'll pass, thank you.

<iframe title="Rolling Stones Factory Girl (Live) - YouTube" width="560" height="315" src="https://www.youtube.com/embed/4jKix2DFlnA"
frameborder="0" allowfullscreen></iframe>

## I'm Moving On (To Factories)

After being introduced to factories by various blogs and coworkers, I looked for
a plugin to get me started. I tried out object daddy and a couple others, but
none of them quite scratched that itch I needed to reach. Some had questionable
implementations, some had poor (or no) tests themselves, and none of them
supported everything we wanted: a nice definition syntax, support for multiple
build strategies (saved instances, unsaved instances, attribute hashes, and
potentially mock objects), and support for multiple factories for the same class
(user, admin\_user, and so on).

Eventually, I ended up just writing little methods that I included in
Test::Unit::TestCase:

```ruby
def create_post (attribs = {})
  attribs = {
    :title     => 'goodbye, fixtures',
    :approved => true
  }.update(attribs)
  attribs[:author] ||= create_user
  Post.create!(attribs)
end
```

It got the job done, and I was finally free of fixtures, but my factory
definitions were hard to follow, and became repetitive pretty fast. After
discussing the pros and cons of the various implementations we'd tried, several
thoughtbotters and I wrote out our ideal syntax for defining and using
factories, and this weekend that theoretical syntax became a reality.

## ~~She's~~ It's a Rainbow

Introducing [factory_bot](https://github.com/thoughtbot/factory_bot/tree/master):

```ruby
# test/test_helper.rb

require 'factory_bot'

# Let's define a sequence that factories can use.  This sequence defines a
# unique e-mail address.  The first address will be "somebody1@example.com",
# and the second will be "somebody2@example.com."
Factory.sequence :email do |n|
  "somebody#{n}@example.com"
end

# Let's define a factory for the User model. The class name is guessed from the
# factory name.
Factory.define :user do |f|
  # These properties are set statically, and are evaluated when the factory is
  # defined.
  f.first_name 'John'
  f.last_name  'Doe'
  f.admin      false
  # This property is set "lazily." The block will be called whenever an
  # instance is generated, and the return value of the block is used as the
  # value for the attribute.
  f.email      { Factory.next(:email) }
end

Factory.define :post do |f|
  f.title    'undef toggle!'
  f.approved true
  # Lazy attribute blocks are passed a proxy object that can be used to
  # generate associations lazily. The object generated will depend on which
  # build strategy you're using. For example, if you generate an unsaved post,
  # this will generate an unsaved user as well.
  f.author   {|a| a.association(:user) }
end

# Let's define a factory with a custom classname:
Factory.define :admin_user, :class => User do |f|
  f.first_name 'Billy'
  f.last_name  'Idol'
  f.email      { Factory.next(:email) }
  f.admin      true
end
```

These factories can be used like so:

```ruby
# test/post_test.rb

class PostTest < Test::Unit::TestCase

  should "only find approved posts" do
    # Generate and save some Post instances
    Factory(:post, :approved => false)
    Factory(:post, :approved => true)

    posts = Post.approved
    assert posts.all? {|p| p.approved? }
  end

  context "a post without a title" do

    setup do
      # Build a post object
      @post = Factory.build(:post, :title => '')
    end

    should "not be valid" do
      assert !@post.valid?
    end

  end

end
```

Combined with Shoulda's contexts, factory\_bot makes tests readable, <abbr
title="Don't Repeat Yourself">DRY</abbr>, and explicit. Until I find another
itch to scratch, I'm in testing heaven.

## You Better Move On

Want to try it out for yourself? factory\_bot is available on
[github](https://github.com/thoughtbot/factory_bot/tree/master). You can also
install it using RubyGems:

```sh
sudo gem install thoughtbot-factory_bot --source=http://gems.github.com
```

Also, make sure to check out the [rdoc](http://dev.thoughtbot.com/factory_bot).

**Update:** Do you have questions or comments on factory\_bot?
Feel free to post them on the new
[mailing list](https://groups.google.com/group/factory_girl).

Happy testing!

* * *

**Disclaimer:**

FactoryGirl was renamed to FactoryBot in 2017.
[Project name history can be found here.](https://github.com/thoughtbot/factory_bot/blob/master/NAME.md)
