[QA]buildとFakerのつかいわけ
投稿機能の結合テストのおけるbefore内の記述について。
●なぜTxetインスタンスをbuildしないのか
RSpec.describe "テキスト投稿", type: :system do
before do
@user = FactoryBot.create(:user)
@text = Faker::Lorem.sentence
end
FactoryBotのtexts.rbファイルには、
アソシエーションの記述がある。
FactoryBot.define do
factory :text do
text {Faker::Lorem.sentence}
association :user
end
end
つまりtextインスタンスを生成すれば、
userインスタンスも自動生成される。
ならば、textインスタンスのみbuildすれば
1行で済むのではないかと考えた。
●仮説と検証
RSpec.describe "テキスト投稿", type: :system do
before do
@text = FactoryBot.create(:text)
end
上記に変更し、テストを実行。
だが、ユーザーログインでエラーが発生。
ユーザー情報は、ログインページに入力されるが、
ログインができない。
そこで、やっと気づく。
ユーザーはたしかに生成される。
だが、createではなく、build状態のユーザー。
つまり、データベースに保存されていない。
言い換えるなら、ユーザー登録がすんでいないユーザーである。
ログインしないと、テキスト投稿できない仕様のため、
このユーザーでテキスト投稿テストをするなら
登録処理が必要になってしまう。
そのため、ユーザーインスタンスを別でbuildしていたということだ。
また、userインスタンスに加えて、
textインスタンスは生成してしまうと、
今度はユーザーが2人になってしまう。
ユーザー登録したユーザーで、テキスト投稿をしたいため、
テキストインスタンスのアソシエーションが働くと不都合。
なので、textはFakerで作成していた。
●質問後に気づいたこと
上記のようなシステム的 理由もあるが、
そもそも「テキスト投稿ができるか」というテストなので
テキストインスタンスをbuildしてしまうと、ニュアンスがズレる。
テキストインスタンスをbuildし、saveできる事を確認するテストなので
用意したテキストインスタンスのテキスト属性を代入して
レコード作成するのではなく、
純粋なテキストだけを用意して、
テキストインスタンスがつくれるかテストするのが
本来の意図に沿ったテストコードとなる。
考察したことは間違っていないが、
テストの捉え方が間違っていた。