はじめに
RSpecでテストを記述する際、ファクトリの生成方法にいくつか種類があり、混同したので一度整理してみる。
環境
Ruby 3.0.3
Rails 6.1.4
rspec-rails 5.0.2
factory_bot_rails 6.2.0
前提
factoryファイルを以下のように記述し、挙動を確認します。
(ユーザーが会社の情報を投稿できるようなアプリケーションを想定しています)
spec/factories/companies.rb
FactoryBot.define do
factory :company do
sequence(:company_name) { |n| "company_#{n}" } # 会社名
company_overview { 'sample_overview' } # 会社の概要
company_address { 'sample_address' } # 所在地
company_num_of_emp { '100-150' } # 従業員数
user
end
end
spec/factories/users.rb
FactoryBot.define do
factory :user do
name { Faker::Name.name }
sequence(:email) { |n| "test#{n}@example.com" }
password { Faker::Internet.password(min_length: 8) }
password_confirmation { password }
end
end
ファクトリの生成方法
build
- メモリ上にインスタンスを保存するだけでDBには保存しない
-
id
やtimestamp
にはnil
が指定される - 関連先のデータはDBに保存されない
- バージョンアップで変更された(参考)
戻り値: 作成されたインスタンス
> company = FactoryBot.build(:company)
> company
=>
#<Company:0x00005576a19bdbe8
id: nil,
company_name: "company_1",
company_address: "sample_address",
company_overview: "sample_overview",
company_num_of_emp: "100-150",
created_at: nil,
updated_at: nil,
user_id: nil>
> company.user
=> #<User id: nil, provider: "email", uid: "", allow_password_change: [FILTERED], name: "Jen Schumm", company_id: nil, newgra_or_midcar: nil, eng_category: nil, admin: false, image: nil, email: "test1@example.com", created_at: nil, updated_at: nil>
build_stubbed
-
id
には適当な値が指定される -
timestamp
は実際の時間が指定される - 関連先のデータはDBに保存されないがidが紐づけられる
戻り値: 作成されたインスタンス
> company = FactoryBot.build_stubbed(:company)
> company
=>
#<Company:0x00005576a5d99e98
id: 1002,
company_name: "company_2",
company_address: "sample_address",
company_overview: "sample_overview",
company_num_of_emp: "100-150",
created_at: Sat, 05 Feb 2022 04:00:57.000000000 UTC +00:00,
updated_at: Sat, 05 Feb 2022 04:00:57.000000000 UTC +00:00,
user_id: 1001>
> company.user
=> #<User id: 1001, provider: "email", uid: "", allow_password_change: [FILTERED], name: "Julianne Hayes MD", company_id: nil, newgra_or_midcar: nil, eng_category: nil, admin: false, image: nil, email: "test2@example.com", created_at: "2022-02-05 04:00:57.000000000 +0000", updated_at: "2022-02-05 04:00:57.000000000 +0000">
create
- インスタンスを作成したのち、DBに保存する
戻り値: 作成されたインスタンス
> company = FactoryBot.create(:company)
...(データベースに保存)...
> company
=>
#<Company:0x00005576a5f60588
id: 146,
company_name: "company_3",
company_address: "sample_address",
company_overview: "sample_overview",
company_num_of_emp: "100-150",
created_at: Sat, 05 Feb 2022 04:02:27.000000000 UTC +00:00,
updated_at: Sat, 05 Feb 2022 04:02:27.000000000 UTC +00:00,
user_id: 7>
> company.user
=> #<User id: 7, provider: "email", uid: "test3@example.com", allow_password_change: [FILTERED], name: "Nancey Lemke", company_id: nil, newgra_or_midcar: nil, eng_category: nil, admin: false, image: nil, email: "test3@example.com", created_at: "2022-02-05 04:02:27.000000000 +0000", updated_at: "2022-02-05 04:02:27.000000000 +0000">
attributes_for
- FactoryBot の定義から、値を Hash 形式で受け取る。
戻り値: 作成されたインスタンスのパラメータ(ハッシュ)
> company = FactoryBot.attributes_for(:user)
> company
=>
{:company_name=>"company_4",
:company_overview=>"sample_overview",
:company_address=>"sample_address",
:company_num_of_emp=>"100-150"}
##参考
https://github.com/thoughtbot/factory_bot/blob/master/GETTING_STARTED.md#using-factories