問題
単体テストコードで「コメントが保存できる時」というテストを行った。
その際にFactoryBotで作成した外部キーであるskill_idとuser_idは存在するのになぜかその二つが空だと言われた。
エラー文
1) Comment コメント投稿 コメント投稿がうまくいくとき コメントが存在すれば登録できる
Failure/Error: expect(@comment).to be_valid
expected #<Comment id: nil, text: "v5tycc16e03hixch09y3661diocp6t5mwqj11r26gbjnptc0ty...", skill_id: 2, user_id: 1, created_at: nil, updated_at: nil> to be valid, but got errors: Userを入力してください, Skillを入力してください
# ./spec/models/comment_spec.rb:11:in `block (4 levels) in <top (required)>'
Finished in 0.78208 seconds (files took 6.7 seconds to load)
3 examples, 1 failure
結論
外部キーのバリデーションをチェックする時にはbuildではなくcreateでデータベースにアクセスすることで値を取得する。
見た目上ではskill_idとuser_idが存在していたが、migrationファイルで外部キー制約をかけているため、それらの値は別テーブルから持ってきた値でなければならない、ということだった。
構造
###before
factorybot
FactoryBot.define do
factory :comment do
text { Faker::Lorem.characters(number: 100) }
user_id { 1 }
skill_id { 2 }
end
end
comment_spec.rb
require 'rails_helper'
RSpec.describe Comment, type: :model do
describe 'コメント投稿' do
before do
@comment = FactoryBot.build(:comment)
end
context 'コメント投稿がうまくいくとき' do
it 'コメントが存在すれば登録できる' do
expect(@comment).to be_valid
end
end
...
after
factorybot
FactoryBot.define do
factory :comment do
text { Faker::Lorem.characters(number: 100) }
association :user
association :skill
end
end
comment_spec.rb
require 'rails_helper'
RSpec.describe Comment, type: :model do
describe 'コメント投稿' do
before do
@comment = FactoryBot.create(:comment)
end
context 'コメント投稿がうまくいくとき' do
it 'コメントが存在すれば登録できる' do
expect(@comment).to be_valid
end
end
...