FactoryBotの使い方や導入方法をメモしておきます。
FactoryBotを使うには
1, gemのインストール
gem "factory_bot_rails"
bundle installを実行する。
2, ジェネレートする
rails g factory_bot:model モデル名
spec/factories
というディレクトリが生成される。その中にモデル名s.rb
というファイルが生成される。このファイルにテストデータを作成していく。
FactoryBotの使い方(例としてUserモデルを扱う)
サンプルデータの作成
FactoryBot.define do
#この中に書いていく
factory :user do
first_name { "aaa" }
last_name { "aaa" }
email { "aaa@example.com" }
password { "password" }
end
end
サンプルデータを呼び出す
user = FacrtoryBot.build(:user)
オーバーライド
以下は性をnilに上書きした。
FactoryBot.build(:user, last_name: nil)
シーケンス
ユニークな値を作りたい時に便利。
factory :user do
first_name { "aaa" }
last_name { "aaa" }
sequence(:email) { |n| "sample#{n}@example.com" }
password { "password" }
end
Userオブジェクトがcreateまたはbuildされるたびにんが1づつ増えるので、上記の場合emailは必ずユニークな値になる。
関連付け
前提:UserモデルとPostモデルが存在し、一対多の関係。
factory :post do
title: { "旅行" }
content: { "めっちゃ楽しかった〜〜" }
association :user
end
これでPostオブジェクトも作られる。(Postオブジェクトのテストデータを作成する時に、紐づくuserを新しく作っているので注意。)
関連付けの際にclass_nameを使っている場合
例えば以下のようにclass_nameを定義している場合。posterは投稿する人という意味。
class_nameについてはこちら。(https://qiita.com/wacker8818/items/eccdf0a63616feb14a70)
class Post < ApplicationRecord
belongs_to :poster, class_name: 'User', foreign_key: :user_id
end
クラスメソッドにより生成される魔法のマッチャ
以下のようなクラスメソッドを定義しているとする。(Userオブジェクトの年齢が13歳未満であればtrueを返すメソッド。)
class User < ApplicationRecord
def kid?
age < 13
end
end
するとbe_kid
というマッチャをRSpecが自動生成してくれる。実際に使ってみる。
it "12歳はまだ子供である" do
FactoryBot.build(:user, age:12)
expect(user).to be_kid
end
テストデータの継承
2つ目以降のuserを作る時にはtrait
メソッドを使うことで簡単に作れる。
factory :user do
first_name { "aaa" }
last_name { "aaa" }
sequence(:email) { |n| "sample#{n}@example.com" }
password { "password" }
trait :second do
first_name { "bbb" }
last_name { "bbb" }
end
end
traitで定義したテストデータを呼び出すときは以下のように書く。
user_second = FactoryBot.build(:user, :second)
これでbbb bbbといったユーザーが作られた。
コールバック
RSpecでもbefore_action的なことができる。
以下の例ではコールバックを使って、Userがオブジェクトを作った直後に3つのPostオブジェクトを自動生成する。