I'm having a little trouble with one of my model specs. I recenttly added a custom validation to the model and now model_spec breaks in one of the validations. Here is my model target.rb:
class Target < ApplicationRecord
validate :targets_count, on: :create #custom validation
validates :title, presence: true
validates :radius, presence: true, numericality: { greater_than: 0 }
validates :lat, :lon, presence: true, numericality: true
belongs_to :user
belongs_to :topic
def targets_count
return unless user.targets.count >= 3
errors.add(:base, "You can't create more than 3 targets")
end
end
And here is the spec:
require 'rails_helper'
RSpec.describe Target, type: :model do
describe 'validations' do
subject { build :target }
it { is_expected.to validate_presence_of(:title) }
it { is_expected.to validate_presence_of(:radius) }
it { is_expected.to validate_presence_of(:lat) }
it { is_expected.to validate_presence_of(:lon) }
it { is_expected.to belong_to(:user) }
it { is_expected.to belong_to(:topic) }
it { is_expected.to validate_numericality_of(:radius).is_greater_than(0) }
it { is_expected.to validate_numericality_of(:lat) }
it { is_expected.to validate_numericality_of(:lon) }
end
end
Every test pass except this one:
it { is_expected.to belong_to(:user) }
And the console returns this error message:
Target validations is expected to belong to user required: true
Failure/Error: return unless user.targets.count >= 3
NoMethodError:
undefined method `targets' for nil:NilClass
return unless user.targets.count >= 3
^^^^^^^^
# ./app/models/target.rb:29:in `targets_count'
# ./spec/models/target_spec.rb:30:in `block (3 levels) in <top (required)>'
If I comment out the custom validation then every test pass.
I'm using FactoryBot and here are the factories for targets and users
FactoryBot.define do
factory :target do
title { Faker::Name.name }
radius { Faker::Number.between(from: 1.0, to: 600_000.0).round(2) }
lat { Faker::Address.latitude }
lon { Faker::Address.longitude }
association :user, factory: :user
association :topic, factory: :topic
end
end
FactoryBot.define do
factory :user do
email { Faker::Internet.unique.email }
password { Faker::Internet.password(min_length: 8) }
username { Faker::Internet.unique.user_name }
first_name { Faker::Name.unique.name }
last_name { Faker::Name.unique.last_name }
uid { Faker::Internet.uuid }
end
end
Any help will be much appreciated!!!
To test this line
RSpec needs checks what happens if there is no
userassigned.But when there is no
userassigned, then this lineraises an error because it calls
targetsonnil.I would argue that the
targets_countvalidation is not required if there is nouserassigned yet. Therefore I would fix this issue by changing that method to