Rspecで多対多のFactoryを作ってSystemSpecでテストしたときのノート[RSpec, FactoryBot]
背景
Rspecで多対多の関係を作って、SystemSpecでテストをしました。
元々のテーブル構造の複雑さもあり、かなり苦労したので、以下にノートをまとめます。
実行完了は下記の通りです。
- Rspec 3.9
- Rails 5.2.4.2
テーブル構造
テーブル構造は、このようになっています。メインのテーブルは、offices
(ある会社の支社)とshops
(営業先である店舗)で、office
(支社)はevebt
を開いて、そこに営業先である店舗shops
が参加します。shops
は必ず何らかのcategory
を持っています。
起こっていた問題
モデルメソッドの関係で、どうしてもevents
のfactory
を作った時に、それに紐づく、shops
が必要になりました。しかし、構造上、このように書いたのでは、エラーが出てしまいました。
let!(:shop){FactoryBot.create(:shop)}
let!(:event){FactoryBot.create(:event)}
#=> ここで eventに紐づくshopがないとエラーになる構造になっていた
let!(:event_shops){FactoryBot.create(:event_shop, event: event, shop: shop)}
対処方法
そこで、event
のfactory
生成時に、同時に関連するshop
も定義できるようなfactoryを作成することにしました。
eventsのファクトリを作る
作成したFactoryは以下のようになっています。
FactoryBot.define do
factory :event do
office_id { nil }
name { "テストイベント" }
trait :with_shops do
after(:create) do |event|
category = FactoryBot.create(:category, :sequence)
create_list(:shop, 1, events: [event], category: category)
end
end
end
end
まず、event
のファクトリ内にwith_shops
というtraitを作成して、event
作成時に関連するshop
も作成できるようにします。create_list
でshop
のファクトリを複数作成でき流ようにし(ここでは1つしか必要ないので1つだけ)、events
からevent
のインスタンスが複数入れられるように、[event]
と配列で表記します。
なお、category
がわざわざtrait
を使って呼び出してあるのは、後ほど解説します。
System Specで適切に呼び出せるようにする
FactoryBot.define do
factory :category do
name { "医療系" }
trait :sequence do
sequence(:id, 100)
name { "服飾系" }
end
end
end
let!(:event) { FactoryBot.create(:event, :with_shops, office: office, shops: [shop]) }
# ここからcategoryをshopに当てはめることはできない
次に、category
のファクトリですが、ビューの中で、event
は複数回生成されます。そのため、同時に生成されるshop
のcateogory
は毎回別のid
(FK)にしないと、FKの重複エラーになってしまいました。
また、system spec
からevent
のshops
にcategory
を当てはめようとすると、spec/factories/events.rb
内で、shop
のファクトリを作成しようとしたときに、「外部キーが存在しません」とエラーになってしまいました。
そのため、sequence
を利用して、一つ一つ違うid
(FK)のcategoryを作成するようにしました。
終わりに(参考サイトなど)
解決に長い時間がかかってしまいましたが、なんとか解決できてよかったです!
今回はDBの構造が複雑だったため、このような複雑なSpecを書かねばならなくなってしまいましたが、
今後はDB設計をしっかりして、もっとシンプルなテストで済むようにしたいです。。。。
▼特に参考にさせていただいた記事など
- FactoryGirlで「多対多」や「複数の1対多」のアソシエーションを設定する
- Factorybotのtraitを使って、has_manyが2重にある複雑なassociation付きのデータを用意する
- FactoryBot (旧FactoryGirl) の sequence と .next
Author And Source
この問題について(Rspecで多対多のFactoryを作ってSystemSpecでテストしたときのノート[RSpec, FactoryBot]), 我々は、より多くの情報をここで見つけました https://qiita.com/tanutanu/items/dc1d4f94713add33d5b5著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .