Reputation: 13221
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!
Upvotes: 117
Views: 67528
Reputation: 6650
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.
Upvotes: 6
Reputation: 6815
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)}
"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
Upvotes: 150
Reputation: 381
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).
Upvotes: 22