Rails: меньше чем проверка делает тест RSpe c неудачным - PullRequest
1 голос
/ 03 мая 2020

Использование:

  • Ruby 2.6.6
  • Рельсы 6.0.2.2

У меня есть модель, Part, которая имеет 2 поля, quantity_available и minimum_order.

У меня есть следующие проверки, чтобы убедиться, что:

  • minimum_order и quantity_available должны существовать
  • minimum_order и quantity_available не может быть 0 или отрицательное
  • minimum_order не может быть больше значения, чем quantity_available
class Part < ApplicationRecord
  validates :quantity_available, :minimum_order, presence: true
  validates_numericality_of :quantity_available, :minimum_order, only_integer: true, greater_than: 0
  validates_numericality_of :minimum_order, only_integer: true, less_than: :quantity_available
end

Проверка работает нормально, когда я проверяю ее вручную с помощью rails console для создания новой детали это противоречит приведенным выше проверкам, однако один из моих тестов RSpe c не проходит

# RSpec
RSpec.describe Part, type: :model do
  let(:part) { Part.new(quantity_available: 250, minimum_order: 10)} 

  it 'is not valid without a Quantity Available' do
    part.quantity_available = nil
    expect(part).to_not be_valid
  end
end
# Console Error
Failures:

  1) Part basic checks is not valid without a Quantity Available
     Failure/Error: expect(part).to_not be_valid

     TypeError:
       cant convert nil into Float
     # ./spec/models/part_spec.rb:32:in `block (3 levels) in <top (required)>'

Как вы можете видеть, это очень простой тест, который просто утверждает, что деталь, у которой нет quantity_available должен потерпеть неудачу, однако в этом случае он технически потерпит неудачу, просто не так, как я хочу, чтобы он потерпел неудачу.

Мое лучшее предположение, что он, вероятно, как-то связан с объявлением quantity_available как nil в тесте, вызывающем пересечение проводов где-то, поскольку он не может проверить все 3 условия. У меня есть тест для minimum_order, который идентичен описанному выше, но он проходит, как и ожидалось.

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

Ответы [ 2 ]

1 голос
/ 04 мая 2020

Полагаю, символ не соответствует значению поля, попробуйте передать лямбду следующим образом:

validates_numericality_of :minimum_order, 
                          only_integer: true, 
                          less_than: -> { quantity_available }
0 голосов
/ 04 мая 2020

Я думаю, что, возможно, я нашел хорошее решение, которое не просто обходной путь, который фактически не решает исходную проблему, с которой я столкнулся при тестировании.

Выполнение следующего при rails c throws ошибка валидации, как и ожидалось:

new = Part.create(available_quantity: 0, minimum_order: 10)
new.save # => false
new.errors.full_messages # => ["Quantity available must be greater than 0", "Minimum order must be less than or equal to 0"]

Как видите, две валидации работают точно так, как ожидалось, но проблема в тесте заключается в том, что одна валидация фактически мешает другой, что очевидно, вызывает проблемы с прохождением теста.

На данный момент есть два варианта, которые я видел, чтобы продолжить:

  1. Сделайте этот конкретный c test также имеет значение nil для поля minimum_order.

Это приводит к небольшому повторению кода и просто в целом не достаточно хорошо для моих вкусов

Просто пропустите проверку, если текущее значение поля quantity_available равно нулю или 0.

Это имеет гораздо больший смысл. В конце концов, 1-я проверка гарантирует, что 0 никогда не попадет в БД ни для одного из этих полей, поэтому можно просто пропустить 2-ю проверку, если присутствует 0 или nil . Если это не так, проверка сработает, и только тогда она сравнит два значения.

Решение, таким образом, довольно простое; Просто вставьте unless: в проверку, которая оценивает лямбду

validates_numericality_of :minimum_order, less_than: :quantity_available, unless: -> { quantity_available.nil? || quantity_available == 0 }

. При этом все тесты становятся зелеными, обходных путей не требовалось, и я уверен, что моя модель является крошечной, более эффективной в проверка его достоверности

...