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'

2. Add to your spec/rails_helper config block:

RSpec.configure do |config|
  #  Other config code
  config.include FactoryGirl::Syntax::Methods  # Add this line

3. Define factory

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. you can use sequence to auto generate username for you.

Factory: the user do the sequence (: username) {n | | "user# {n}} to the 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, 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.

If you have any comments or suggestions, or find any questions in the article, please leave a comment!

More articles please visit personal blog author: zou small gen Github:https://github.com/ChrisZou mail: [email protected]