Stubbing for custom validation in Minitest triggers validation error, but stubbed value not recognized

59 Views Asked by At

I am using Custom Validators in my Ruby on Rails project.

I have defined the validator

class RecognisedCountryValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    countries = client_config.countries
    return if countries.include?(value)

    if countries.size == 1
      record.errors.add(attribute, :equal_to_value, value: countries.first)
    else
      record.errors.add(attribute, :inclusion_in_list, list: countries.join(', '))
    end
  end
end

after that I validated the :country attrbute in the Location class like so:

validates :country, recognised_country: true

The validation works, however, the problem now is that stubbing in the test isn't working. I am testing my models with Minitest and when I try to write

subject.client_config.stub(:countries, ['France']) do
  assert_invalid 'must be France', country: 'UK'
end

Instead of getting 'must be France' validation error I am getting 'must be USA' error(This value is set initially, however, I would like to change it with stubbing to France for example which doesnt seem to be working. Any ideas?

I have tried stubbing differently, with return method too, but the outcome isn't what I expect anyway.

It is also worth noting that when the validator was written this way

module RecognisedCountryValidation
  extend ActiveSupport::Concern

  included do
    validate :must_be_from_recognised_country
  end

  private

  def must_be_from_recognised_country
    countries = client_config.countries
    return if countries.include?(country)

    if countries.size == 1
      errors.add(:country, :equal_to_value, value: countries.first)
    else
      errors.add(:country, :inclusion_in_list, list: countries.join(', '))
    end
  end
end

and then RecognisedCountryValidation was included in the Location class, everything with stubbing worked fine.

In the client config the countries array is set to ["USA"], can't share the whole client_config though.

SOLUTION Had to call client_config.countries on the record(in this case Location) itself.

countries = record.client_config.countries

0

There are 0 best solutions below