FactoryGirl中的build和create方法之间有什么区别?


94

《工厂女郎》简介描述了FactoryGirl.build()和之间的区别FactoryGirl.create()

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

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

我仍然不了解两者之间的实际差异。有人可以举一个您想使用一个而不是另一个的示例吗?谢谢!

Answers:


115

create()方法将模型的实例持久化,而build()仅将其保存在内存中。

就个人而言,我create()仅在确实需要持久性的情况下才使用该方法,因为写入DB会浪费测试时间。

例如

我创建用于身份验证的用户,create()因为身份验证引擎查询数据库。

要检查模型是否具有属性,该build()方法将执行此操作,因为不需要数据库访问。

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

更新资料

“在建立关联时,构建实际上会“创建”一个例外,即您的关联不再在内存中,而是持久存在。请记住这一点” –摇


14
建立关联时,构建实际上会“创建”一个例外,即您的关联不再在内存中,而是持久存在。记住这一点
2014年

@Shakes,我不再在路轨上工作了。我会尽快检查。
Helio Santos 2014年

有没有人做了一个工具来代替每个实例createbuild,并撤消它,如果测试失败?
mgold

#create阅读并从磁盘返回持久对象呢,还是坚持它后返回的对象在内存中的?换句话说,create(...)等同于create(...).reload吗?
丹尼斯

@mgold Vim在这种事情上非常擅长。
有限赎罪

15

使用FactoryGirl.build(:factory_name)不会持久化到数据库,也不会调用save!,因此您的Active Record验证将不会运行。这要快得多,但是验证可能很重要。

使用FactoryGirl.create(:factory_name)将一直保留到数据库,并将调用Active Record验证。这显然较慢,但可以捕获验证错误(如果您在测试中关心它们)。


11
或者,您可以只执行FactoryGirl.build(:factory_name).valid吗?运行验证而不保存到数据库。
jinavar1 2014年

1

FactoryGirl.create()将为其创建新的对象和关联(如果工厂有)。它们都将保存在数据库中。同样,它将触发模型和数据库验证。回调after(:build)after(:create)将在保存工厂后调用。也before(:create)将在保存工厂之前调用。

FactoryGirl.build()不会保存对象,但如果工厂具有关联,仍会向数据库发出请求。它将仅触发关联对象的验证。after(:build)建立工厂后将调用回调。

请注意,在大多数情况下,最好使用测试模型以build_stubbed获得更好的性能。在此处了解更多信息。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.