Reputation: 2222
I have a model 'Policy'. Within that model, I have presence validations for policy_holder and premium_amount. I'm attempting to write a MiniTest test for this model. For some reason, my tests are failing.
Here is my model:
class Policy < ApplicationRecord
belongs_to :industry
belongs_to :carrier
belongs_to :agent
validates :policy_holder, presence: true
validates :premium_amount, presence: true
end
And here are my tests:
require 'test_helper'
class PolicyTest < ActiveSupport::TestCase
test 'should validate policy holder is present' do
policy = Policy.find_or_create_by(policy_holder: nil, premium_amount: '123.45',
industry_id: 1, carrier_id: 1,
agent_id: 1)
assert_not policy.valid?
end
test 'should validate premium amount is present' do
policy = Policy.find_or_create_by(policy_holder: 'Bob Stevens', premium_amount: nil,
industry_id: 1, carrier_id: 1,
agent_id: 1)
assert_not policy.valid?
end
test 'should be valid when both policy holder and premium amount are present' do
policy = Policy.find_or_create_by(policy_holder: 'Bob Stevens', premium_amount: '123.45',
industry_id: 1, carrier_id: 1,
agent_id: 1)
assert policy.valid?
end
end
Here is the failure message:
Failure:
PolicyTest#test_should_be_valid_when_both_policy_holder_and_premium_amount_are_present [test/models/policy_test.rb:22]:
Expected false to be truthy.
The last test is failing when I believe is should be passing. This has me thinking that my other tests are not correct either.
Upvotes: 3
Views: 1528
Reputation: 102036
There is a much easier way to test validations with less "carpet bombing" involved:
require 'test_helper'
class PolicyTest < ActiveSupport::TestCase
setup do
@policy = Policy.new
end
test "should validate presence of policy holder" do
@policy.valid? # triggers the validations
assert_includes(
@policy.errors.details[:policy_holder],
{ error: :blank }
)
end
# ...
end
This tests just that validation and not every validation on the model combined. Using assert policy.valid?
will not tell you anything about what failed in the error message.
errors.details
was added in Rails 5. In older versions you need to use:
assert_includes( policy.errors[:premium_amount], "can't be blank" )
Which tests against the actual error message. Or you can use active_model-errors_details which backports the feature.
Upvotes: 6
Reputation: 59
So what's happening here is the validations are failing on the model.
.valid?
will return true
if there are no errors on the object when the validations are run.
Since you are clearly seeing a "false", that means one or more of the validations on the model are failing.
In a Rails console, you should try creating an object manually and casting it to a variable, then testing it to see the errors thusly:
test = Policy.new(whatever params are needed to initialize here)
# This will give you the object
test.valid?
#This will likely return FALSE, and NOW you can run:
test.errors
#This will actually show you where the validation failed inside the object
Regardless, this is almost assuredly a problem in the model and its creation.
Keep in mind, .errors
won't work until AFTER you run .valid?
on the object.
Upvotes: -1