Сбой RSpec при использовании пользовательского валидатора - PullRequest
2 голосов
/ 14 ноября 2011

Я использую такой вид проверки в моем проекте rails 3.1.

validates_presence_of :sales_price
validates_presence_of :retail_price
validates_numericality_of :sales_price, :greater_than => 0,
                          :allow_blank => true
validates_numericality_of :retail_price, :greater_than => 0,
                          :allow_blank => true

validate :sales_price_less_than_retail

def sales_price_less_than_retail
  if sales_price >= retail_price
    errors.add(:sales_price, "must be less than retail price.")
  end
end

Я тестирую модели, используя rspec. Все было хорошо, когда я использовал только рельсы стандартных помощников проверки. Но когда я написал пользовательский валидатор (sales_price_less_than_retail), тесты начали проваливаться.

Вот код теста:

it { should validate_presence_of :sales_price }
it { should validate_presence_of :retail_price }
it { should validate_numericality_of :sales_price }
it { should validate_numericality_of :retail_price }

Вот фабрика:

Factory.define :offer_option do |f|
  f.sales_price          rand(21) + 10  # $10-$30
  f.retail_price         { |a| a.sales_price * 2 }
end

Когда я запускаю тест, я получаю такие ошибки:

Неудачи:

1) OfferOption

Failure/Error: it { should validate_presence_of :sales_price }
 NoMethodError:
   undefined method `>=' for nil:NilClass
 # ./app/models/offer_option.rb:38:in `sales_price_less_than_retail'
 # ./spec/models/offer_option_spec.rb:18:in `block (2 levels) in <top (required)>'

2) OfferOption

 Failure/Error: it { should validate_presence_of :retail_price }
 ArgumentError:
   comparison of BigDecimal with nil failed
 # ./app/models/offer_option.rb:38:in `>='
 # ./app/models/offer_option.rb:38:in `sales_price_less_than_retail'
 # ./spec/models/offer_option_spec.rb:19:in `block (2 levels) in <top (required)>'

Я думаю, все должно быть в порядке, потому что rspec должен тестировать валидаторы отдельно, но кажется, что он вызывает собственный валидатор после вызова validates_presence_of в моем тесте. Проблема исчезает, когда я удаляю пользовательский валидатор.

Что я делаю не так?

1 Ответ

6 голосов
/ 14 ноября 2011

Я предполагаю, что это потому, что validate_presence_of rspec helper установил offer_option.sales_price = nil и затем вызвал valid?на offer_option.При вызове valid ?, он запускает все ваши проверки, так же как и пользовательские проверки.И тогда вы получите эту ошибку, потому что нет метода '> =' для nil.

, если вы измените sales_price_less_than_retail на:

def sales_price_less_than_retail
  return if sales_prices.blank? || retail_price.blank?

  if sales_price >= retail_price
    errors.add(:sales_price, "must be less than retail price.")
  end 
end

Тогда он должен работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...