-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Usage
You can add factories to any of the following places:
- test/factories.rb (Test::Unit)
- spec/factories.rb (RSpec)
- test/factories/*.rb
- spec/factories/*.rb
A typical factory file looks like this:
FactoryGirl.define do
factory :user do
first_name 'John'
last_name 'Doe'
age { 1 + rand(100) }
# Child of :user factory, since it's in the `factory :user` block
factory :admin do
admin true
end
end
end
Make sure to add this to your RSpec configure block:
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
end
Make sure to add this for Test::Unit:
class ActiveSupport::TestCase
include FactoryGirl::Syntax::Methods
end
Make sure to add this for Cucumber (an appropriate place is in the env.rb file):
World FactoryGirl::Syntax::Methods
Once your factories are defined, you can use them in the following ways:
# Saved instance
user = create(:user)
# Unsaved instance
user = build(:user)
# Attribute hash (ignores associations)
user_attributes = attributes_for(:user)
# Stubbed object
user_stub = build_stubbed(:user)
# Override attributes
user = create(:user, first_name: 'Joe')
If you need uniqueness on a field, sequencing comes in handy. The sequences can then be used in your other definitions
FactoryGirl.define do
sequence :email do |n|
"email#{n}@factory.com"
end
factory :user do
email
password "foobar"
password_confirmation "foobar"
end
end
Or you can generate an email anywhere in your code:
new_email = FactoryGirl.generate(:email)
Sequencing can also be defined within the factory definition. This lets you define a sequence that is only incremented when a new user is built or created. Otherwise, FactoryGirl.generate(:email)
would increment the sequence.
FactoryGirl.define do
factory :user do
sequence(:email) {|n| "email#{n}@factory.com" }
password "foobar"
password_confirmation "foobar"
end
end
For completeness’ sake, we can make password_confirmation match the password by using a block to define its value.
FactoryGirl.define do
factory :user do
sequence(:email) {|n| "email#{n}@factory.com" }
password "foobar"
password_confirmation { |u| u.password }
end
end
The sequencing also works for associations. The code below will create a new user with the sequenced email from above.
FactoryGirl.define do
factory :post do
name "Post name"
user
end
end
For a model that has named associations, you can add an alias to a factory. For instance, consider a private message model that has a sender and recipient association for the user table
class Message < ActiveRecord::Base
belongs_to :sender, :class_name => "User",
:foreign_key => 'sender_id'
belongs_to :recipient, :class_name => "User",
:foreign_key => 'recipient_id'
end
factory :user, :aliases => [:sender, :recipient] do
username
password 'secret'
password_confirmation { |u| u.password }
end
Which then could be used as:
FactoryGirl.define do
factory :message do
sender
recipient
end
end