Я использую такой вид проверки в моем проекте 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 в моем тесте.
Проблема исчезает, когда я удаляю пользовательский валидатор.
Что я делаю не так?