Reputation: 228
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!!!
Upvotes: 0
Views: 367
Reputation: 107117
To test this line
it { is_expected.to belong_to(:user) }
RSpec needs checks what happens if there is no user
assigned.
But when there is no user
assigned, then this line
return unless user.targets.count >= 3
raises an error because it calls targets
on nil
.
I would argue that the targets_count
validation is not required if there is no user
assigned yet. Therefore I would fix this issue by changing that method to
def targets_count
return unless user
return unless user.targets.count >= 3
errors.add(:base, "You can't create more than 3 targets")
end
Upvotes: 0