Search code examples
ruby-on-railsruby-on-rails-4fixturesminitest

Rails Model test with minitest and fixture


I've a test in minitest:

class CompanyTest < ActiveSupport::TestCase
  def setup
    @company = companies(:default)
  end

  test 'permalink should present' do
    @company.permalink = "     "
    assert_not @company.valid?
  end
end

Fixture for default company is:

default:
  name: 'default'
  website: 'www.example.com'
  permalink: 'default'

I have validation on company model as(company.rb):

validates :permalink, presence: true,  uniqueness: true
  before_validation :add_permalink

private
  def add_permalink
    self.permalink = self.name.to_s.parameterize
  end

Surprisingly the test is failing.

  test_0001_permalink should present                              FAIL (95.55s)
Minitest::Assertion:         Expected true to be nil or false
        test/models/company_test.rb:31:in `block in <class:CompanyTest>'

I had put a binding.pry on inside rails active-model validator: ActiveModel::Validations::PresenceValidator

class PresenceValidator < EachValidator # :nodoc:
      def validate_each(record, attr_name, value)
        binding.pry
        record.errors.add(attr_name, :blank, options) if value.blank?
      end
    end

Here the record still has permalink as default.

[1] pry(#<ActiveRecord::Validations::PresenceValidator>)> record
=> #<Company:0x007f9ca5375070
 id: 593363170,
 name: "default",
 created_at: Wed, 15 Apr 2015 17:59:56 UTC +00:00,
 updated_at: Wed, 15 Apr 2015 17:59:56 UTC +00:00,
 website: "www.example.com",
 permalink: "default"

Can anyone help me understand why the test is failing and why the record in ActiveModel::Validations::PresenceValidator still exactly matches with fixture data?

UPDATE: Its because of before_validate, which essentially sets the permalink according to name.


Solution

  • You have added a before_validation and when you are calling valid? method it trigger before_validation hook and as you are setting it as name of company and in this case name of comapny is default so that you are getting it in console as 'default'.

    You are explicitly setting the permalink in before_validation hook and testing it for invalid case, which is not possible.