違いに迷ったのでまとめました。
テストデータ
factories/users.rb
FactoryGirl.define do
factory :user do
name '太郎'
email 'taro@exampla.com'
end
end
factories/articles.rb
FactoryGirl.define do
factory :article do
title 'タイトル'
body '本文'
user
end
end
Userは複数のArticleを所持しています。
Articleは一つのUserを所持しています。
buildしたときの挙動
pry-console
pry> article = FactoryGirl.build(:article)
id: nil,
title: 'タイトル',
body: '本文',
user_id: 1
pry> User.last
id: 1,
name: '太郎'
email: 'taro@example.com'
pry> article.user
id: 1,
name: '太郎'
email: 'taro@example.com'
pry> article.user == User.last
=> true
idがnilのテストデータが生成されます。saveは行われていません。
しかし、アソシエーション先のUserを作成しています。
build_stubbedしたときの挙動
pry-console
pry> article = FactoryGirl.build_stubbed(:article)
id: 1001,
title: 'タイトル',
body: '本文'
user_id: 1001
pry> User.last
=> []
pry> article.user
id: 1001,
name: '太郎'
email: 'taro@example.com'
pry> article.user == User.last
=> false
idが付与された状態で生成されます。同じくsaveは行われていません。
こちらでは、アソシエーション先のUserのインスタンスは生成されていますが、保存はされていません。
使い分け
build | build_stubbed | |
---|---|---|
DBに保存 | しない | しない |
アソシエーション先をDBに保存 | する | しない |
アソシエーション先をインスタンス生成 | する | する |
idを生成 | しない | する |
簡単にまとめるとこんな感じでしょうか。 | ||
実際にDBに保存されたデータがテストに必要なときは、create OR buildを使い、余計なI/Oを避けるために、必要のないときはbuild_stubbedを使うというのがベストだと思います。 |
@shuhei さんにコメント頂き、修正しました。ありがとうございます。