こんにちは、まどぎわです(・∀・)
今回はFactoryBotでtrait付きの関連(Association)を定義する方法を知ったのでメモしておきます✍
前提: Quizの正解数ランキングを集計する処理の検証
今回は下記のようなクイズへのユーザーの解答を集計してランキングを作成するようなテストコードを書いたものとします、そこまで悪くなさそうですがcreate(:quiz, :with_choices)
が何度も出てきてしまっているのがイマイチですね😥
let(:no1_user) { create(:user) } let(:no2_user) { create(:user) } let(:no3_user) { create(:user) } before do create(:quiz_user_answer, quiz: create(:quiz, :with_choices), user: no1_user, correct: true) create(:quiz_user_answer, quiz: create(:quiz, :with_choices), user: no1_user, correct: true) create(:quiz_user_answer, quiz: create(:quiz, :with_choices), user: no2_user, correct: true) create(:quiz_user_answer, quiz: create(:quiz, :with_choices), user: no2_user, correct: false) create(:quiz_user_answer, quiz: create(:quiz, :with_choices), user: no3_user, correct: false) create(:quiz_user_answer, quiz: create(:quiz, :with_choices), user: no3_user, correct: false) end it '正解数の降順で取得出来ること' do ranking = described_class.ranking expect(ranking.map(&:user_id)).to eq [no1_user.id, no2_user.id, no3_user.id] end
trait付きの関連(Association)を定義してリファクタリング
こういう場合にtrait付きの関連をfactoryに定義すると便利です👀
FactoryBot.define do factory :quiz_user_answer do association :quiz, :with_choices user correct { [true, false].sample } end end
こんな感じで繰り返しcreate(:quiz, :with_choices)
書かなくていいのでスッキリしますね🙌
let(:no1_user) { create(:user) } let(:no2_user) { create(:user) } let(:no3_user) { create(:user) } before do create(:quiz_user_answer, user: no1_user, correct: true) create(:quiz_user_answer, user: no1_user, correct: true) create(:quiz_user_answer, user: no2_user, correct: true) create(:quiz_user_answer, user: no2_user, correct: false) create(:quiz_user_answer, quiz: user: no3_user, correct: false) create(:quiz_user_answer, quiz: user: no3_user, correct: false) end it '正解数の降順で取得出来ること' do ranking = described_class.ranking expect(ranking.map(&:user_id)).to eq [no1_user.id, no2_user.id, no3_user.id] end