現在RSpecの勉強をしており、dependent: :destroy時のレコード削除テストを実装しています。
現在FoodsテーブルはMenusテーブルに対し、1対多の「has_many :menus, dependent: :destroy」の関係となっています。
FactoryBotで下のようなテストデータを作り、
ruby
1FactoryBot.define do 2 factory :apple, :class => Food do |food| 3 food.name 'りんご' 4 after(:create) do |apple| 5 FactoryBot.create(:pie, food: apple) 6 FactoryBot.create(:juice, food: apple) 7 end 8 end 9end 10
ruby
1FactoryBot.define do 2 factory :pie, :class => Menu do |menu| 3 menu.name "アップルパイ" 4 association :food, factory: :apple 5 end 6 7 factory :juice, :class => Menu do |menu| 8 menu.name "りんごジュース" 9 association :food, factory: :apple 10 end 11end 12
RSpecでモデルの作成と削除のテストを書きました
ruby
1RSpec.describe Menu, type: :model do 2 3 describe "モデル作成・削除テスト" do 4 let(:apple) { FactoryBot.create(:apple) } 5 it "menuが正常に作成できているかどうか" do 6 expect(apple).to be_valid 7 end 8 9 it 'foodを削除すると、foodに紐づくmenuが削除がされること' do 10 #p apple.menus 11 expect{ apple.destroy }.to change{ Menu.count }.by(-2) 12 end 13 14 end 15end
この時テストが失敗したため、ちゃんとデータが作られているか見るため「p apple.menus」で確認したところテストが何故か成功しました。
おそらくletで作った際はそのデータ(メソッド?)にアクセスするまではデータが作られないので、pで明示的にアクセスした際にmenuのデータが作られ、アクセスしない場合は作られずにdestroyテストが失敗したのではないかと思いました。
ruby
1RSpec.describe Menu, type: :model do 2 3 describe "モデル作成・削除テスト" do 4 before { @apple = FactoryBot.create(:apple) } 5 it "menuが正常に作成できているかどうか" do 6 expect(@apple).to be_valid 7 end 8 9 it 'foodを削除すると、foodに紐づくmenuが削除がされること' do 10 expect{ @apple.destroy }.to change{ Menu.count }.by(-2) 11 end 12 13 end 14end
またこのようにletでなくbeforeで作成した際は問題なくテストがパスしました。
letとbeforeの使い分けをいまいち把握してないせいかもしれませんが、この場合はletを使用するのは不適切ということでしょうか。
またこのようなdependent: :destroyの削除テストを書く際に慣習的に正しい書き方があれば教えていただけると助かります。
あなたの回答
tips
プレビュー