見出し画像

[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できる事を確認するテストなので
用意したテキストインスタンスのテキスト属性を代入して
レコード作成するのではなく、

純粋なテキストだけを用意して、
テキストインスタンスがつくれるかテストするのが
本来の意図に沿ったテストコードとなる。

考察したことは間違っていないが、
テストの捉え方が間違っていた。