まず、belongs_to, has_many の関係で外部キーに関するテストを行いたかった。。。。が
書いていたコード
model
class UserName < ApplicationRecord
belongs_to :user
facrtory
FactoryGirl.define do
factory :user_name do
name 'hogehoge'
user_id 1
end
end
model_spec
context 'uniqueness' do
subject { create(:user_background) }
it { is_expected.to validate_uniqueness_of(:user_id) }
end
error
.F
Failures:
1) UserBackground#create should have a unique user_id
Failure/Error: should validate_uniqueness_of(:user_id)
Shoulda::Matchers::ActiveRecord::ValidateUniquenessOfMatcher::ExistingRecordInvalid:
validate_uniqueness_of works by matching a new record against an
existing record. If there is no existing record, it will create one
using the record you provide.
While doing this, the following error was raised:
PG::NotNullViolation: ERROR: null value in column "user_id" violates not-null constraint
DETAIL: Failing row contains (17, null, null, 2017-12-06 20:38:00.990373, 2017-12-06 20:38:00.990373).
: INSERT INTO "user_backgrounds" ("created_at", "updated_at") VALUES ($1, $2) RETURNING "id"
The best way to fix this is to provide the matcher with a record where
any required attributes are filled in with valid values beforehand.
# ./spec/models/user_background_spec.rb:18:in `block (3 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# PG::NotNullViolation:
# ERROR: null value in column "user_id" violates not-null constraint
# DETAIL: Failing row contains (17, null, null, 2017-12-06 20:38:00.990373, 2017-12-06 20:38:00.990373).
# ./spec/models/user_background_spec.rb:18:in `block (3 levels) in <top (required)>'
原因
どうやら、user_id は外部キーであるために直接いれてはいけないらしいです。
ということで、アドバイスをもらいつつこんな感じにもしましたがだめでした。
facrtory
FactoryGirl.define do
factory :user_name do
name 'hogehoge'
user_id user
end
end
解決策
こちらを参考にさせてもらいもらったところこんな感じでいけました。
http://shim0mura.hatenadiary.jp/entry/2014/06/29/002102
factory
FactoryGirl.define do
factory :user_name do
image_url { Faker::File.file_name('path/to') }
association :user, factory: :user
end
end
model_spec
context 'uniqueness' do
subject { create(:user_background) }
it { is_expected.to validate_uniqueness_of(:user_id) }
end
まとめ
belongs_to, has_many が関連するモデルをテストする場合は
model_spec
belongs_to :user
association :user, factory: :user
has_many :user
users {[
FactoryGirl.create(:user)
]}
でassociationをくんであげると善きみたいですね。