FactoryGirl is a gem aimed at replacing Fixtures. If you wonder that, take a look at what's wrong with fixtures.
### 1. Add factory_girl_rails
to your Gemfile
group :test, :development do gem 'factory_girl_rails' end
### 2. Add to your spec/rails_helper config block:
RSpec.configure do |config| # Other config code config.include FactoryGirl::Syntax::Methods # Add this line end
### 3. Define factory
In spec/factories.rb
or test/factories.rb
FactoryGirl.define do factory :user do username ‘foo’ password ‘secret’ email {“#{username}@example.com”} # define value dynamically, pass a block end end
### 4. Use the factory in your spec
user = create(:user) user = create(:user, username: ‘xiaochuang’, password: ‘xiaochuangchuang’) # Override the default value. user = build(:user) # Will not save to database, faster than create
### 5. tips and tricks#### 1. use sequence in model field
Say your user model has a validation of uniqueness for the attribute username
, then if you call create(:user)
multiple times without passing in the username
, you’ll get an error. In this case, you can use sequence
to auto generate username for you.
factory :user do sequence(:username) {|n| “user#{n}”} end
Now everytime you create(:user)
will return a user with a different username in the form: user0, user1, user2...
#### 2. Use associations
Assume you have a Post model that references to a User.
factory :user do username ‘xiaochuang’ password ‘xiaochuangchuang’ end factory :post do title ‘A new post’ user #Yes, it’s just that simple. end
However, the above usage assume that the user field is name user
, if not, you can use association
to customize the behavior.
association :author, factory: :user, username: ‘xiaochuang’
#### 3. Nested factory
Say your user model have an attribute called admin
, this is used frequently and you don’t want to pass in the admin attribute very time. In this case, you can use a nested factory:
factory :user do username ‘xiaochuang’ password ‘xiaochuangchuang’ admin false factory :admin do admin true end end
In your spec, you can just create(:admin)
to create a user that set the admin
to true
.
#### 4. Use build instead of create if possible.
By using create(:model)
, you create the model instance and save if to the database. In many cases if you don’t have to save it the the database, you can use build(:model)
. This will build an instance but wouldn’t save to the database, which makes it a little bit faster.
And also, in many cases you if you can just Model.new
, you can bypass factories at all, which is even faster.