最近RSpecについて勉強している者です。
他の方のポートフォリオを拝見する機会がありまして、
「テストに書いてあるtraitって何だろう?」
と疑問に思ったため、現在理解している点についてアウトプットしました。
(「everyday rails - rspecによるrailsテスト入門」
を参考に勉強している途中です)
間違っている点などありましたらご指摘よろしくお願いします。
traitの使い方
FactoryBotを用いて次のようなテストデータ(ファクトリ)を作成するとします。
FactoryBot.define do
factory :user do
name = "Taro"
name { name }
email = "test1@example.com"
email { email }
password = "pass123"
password { password }
end
end
Userというモデルにnameカラム、emailカラム、passwordカラムが存在しますね。
ここで
「emailだけ『test2@example.com』になっているファクトリを新しく作りたいな」
と考えたとします。その時は「継承」という機能を使うと便利です。
FactoryBot.define do
factory :user do
name = "Taro"
name { name }
email = "test1@example.com"
email { email }
password = "pass123"
password { password }
#新しいファクトリを定義
factory :another_user do
email = "test2@example.com"
email { email }
end
end
end
なぜ「継承」を利用するのかというと、「記述が重複してしまうことを防ぐため」です。
継承を利用しない場合、今回のような規模なら問題ありませんが、これがもっとファクトリ内のインスタンス数が多い中で、「新しいファクトリを定義したい」となった場合、非常に手間です。例えば、「10個のインスタンスがある内の1個だけ属性値を変えたい」という場合でも、その10個全てを再定義しないといけませんから😅
そこで、継承を使うことで、「emailだけ『test2@example.com』のファクトリを新しく作る」ということが可能になります(つまり、記述の重複がなくなる!)。
しかし、複雑なオブジェクトを構築したいときや、テストデータに関する要件がもっと複雑になってきた時は、継承よりも「trait」の方が向いているそうです(こちらに関しては、現在勉強中です。こちらの方が、traitを使う本当の理由のようです)。
継承をtraitにしたい時は、次のように記述します。
FactoryBot.define do
factory :user do
name = "Taro"
name { name }
email = "test1@example.com"
email { email }
password = "pass123"
password { password }
#新しいファクトリを定義
trait :another_user do
email = "test2@example.com"
email { email }
end
end
end
定義したファクトリをspecファイルで呼び出したい時は、以下のように記述します。
user = FactoryBot.create(:user(モデル名), :another_user(ファクトリ名))
このtraitを使用することでも、「記述が重複してしまうことを防ぐこと」ができます。
いかがでしたか?
traitは、複雑なオブジェクトを構築したいときや、テストデータに関する要件がもっと複雑になってきた時にこそ輝くそうなので、今後理解できたら、また内容を更新したいと思います。
ここまで読んでいただきありがとうございました。