hashrocket
hashrocket

Reputation: 2222

MiniTest Model Validation Test Failing

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

Answers (2)

max
max

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

Danodemo
Danodemo

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

Related Questions