
The factory_girl syntax was designed to balance best practices, consistency, readability, and brevity, and to handle all of the features we wanted to support. However, users haven’t been shy to point out that not everybody is a fan of our factory flavor.
If you think mixing in some factory_girl would be good for your project, but don’t care much for the taste, you can try out one of the new alternate syntaxes:
# Use factory_girl machinist-style
require 'factory_girl/syntax/blueprint'
require 'factory_girl/syntax/sham'
require 'factory_girl/syntax/make'
Sham.email {|n| "email#{n}@example.com" }
User.blueprint do
name { 'Billy Bob' }
email { Sham.email }
end
# Or build factories like daddy did
require 'factory_girl/syntax/generate'
User.generate
User.generate!
User.spawn
User.generate {|user| user.something }
Give one of our other flavors a whirl, and let us know what you think.
If you do view testing, or isolation testing in general, you’re probably sick of creating database records that you’re just going to return from a stubbed method anyway. Want pure mock objects? Don’t want to stub out attributes you need for view tests? Use Factory.stub:
context "on GET to show" do
setup do
@user = Factory.stub(:user)
stub(User).find(anything) { @user }
end
should "display the user's name" do
# ...
end
# ... more view tests
end
Sometimes a sequence is required for just a single factory, and defining the sequence separately is just a little too much to type. Got a one-off sequence? Define it inline:
Factory.define :airport do |factory|
factory.sequence(:code) {|n| "AA#{n}" }
end
factory_girl works great for any class that accepts attributes after initialization, like ActiveMerchant CreditCards. However, doing a Factory.build to avoid a save! for other classes can make these factories a little harder to swallow. If you’re using factory_girl for a class that doesn’t use save!, try changing the default strategy:
Factory.define :credit_card,
:class => 'ActiveMerchant::Billing::CreditCard',
:default_strategy => :build do |factory|
# ...attributes for a credit card...
end
Defining attributes you don’t need on a factory can cause your tests to make assumptions they shouldn’t, but it can be pretty inconvenient to repeat all those base attributes for convenient alternate factories. Falling asleep from typing the same attributes over and over? Wake up to the most-requested feature for factory_girl: inheritence!
Factory.define :post do |factory|
factory.title "Every post needs a title!"
end
Factory.define :approved_post, :parent => :post do |factory|
factory.approved true
# Approved posts need to be approved by somebody!
factory.association :approver, :factory => :user
end
The factory_girl docs have been updated and revamped, so be sure to hit those up if you have questions on older or newer functionality.
If you’d like to add another syntax, or have a feature you’re itching for, please create a clone of our repository on github (please be sure to read the contribution guidelines).
Thanks to Josh Nichols for documentation patches, and a big thank you to Eugene Bolshakov for his huge contributions to this release.