What's the difference between the build and create methods in FactoryGirl?
Asked Answered
C

3

115

The Factory Girl introduction delineates the difference between FactoryGirl.build() and FactoryGirl.create():

# Returns a User instance that's not saved
user = FactoryGirl.build(:user)

# Returns a saved User instance
user = FactoryGirl.create(:user)

I still don't understand the practical differences between the two. Can someone give an example where you would want to use one and not the other? Thanks!

Canonry answered 31/12, 2012 at 5:57 Comment(0)
S
149

The create() method persists the instance of the model while the build() method keeps it only on memory.

Personally, I use the create() method only when persistence is really necessary since writing to DB makes testing time consuming.

e.g.

I create users to authentication with create() because my authentication engine queries the DB.

To check if a model has an attribute the build() method will do because no DB access is required.

it{Factory.build(:user).should respond_to(:name)}

Update

"There is one exception that build actually 'creates' when you are building associations, i.e your association are no longer in memory but persisted. Keep that in mind" – Shakes

Sherwin answered 4/1, 2013 at 21:3 Comment(4)
There is one exception that build actually 'creates' when you are building associations, i.e your association are no longer in memory but persisted. Keep that in mindBecome
@Shakes, I don't work in rails anymore. I'll check that as soon as I can.Sherwin
Has anyone made a tool to replace each instance of create with build, and undo it if the test fails?Renounce
Does #create read and return the persisted object from disk, or does it return the object that's in memory after persisting it? In other words, is is doing create(...) equivalent to create(...).reload?Witten
F
22

Using FactoryGirl.build(:factory_name) does not persist to the db and does not call save!, so your Active Record validations will not run. This is much faster, but validations might be important.

Using FactoryGirl.create(:factory_name) will persist to the db and will call Active Record validations. This is obviously slower but can catch validation errors (if you care about them in your tests).

Flip answered 1/8, 2013 at 19:51 Comment(1)
Or, you could just do FactoryGirl.build(:factory_name).valid? which run validations without saving to database.Role
A
6

FactoryGirl.create() will create new object and associations (if the factory has any) for it. They will all be persisted in a database. Also, it will trigger both model and database validations. Callbacks after(:build) and after(:create) will be called after the factory is saved. Also before(:create) will be called before the factory is saved.

FactoryGirl.build() won't save an object, but will still make requests to a database if the factory has associations. It will trigger validations only for associated objects. Callback after(:build) will be called after the factory is built.

Note that in most cases when testing models are best to use build_stubbed for better performance. Read more about it here.

Absolve answered 4/5, 2018 at 10:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.