Я пишу тесты для RoR Gem, проверка которого зависит от переменной конфигурации:
class MyModel < ApplicationRecord
validates_length_of :field_name, minimum: GemName.minimum_field_length
end
Я могу убедиться, что этот параметр конфигурации работает должным образом, однако я хочу убедиться, что он охвачен тестом:
class MyModelTest < ActiveSupport::TestCase
test "field length is validated" do
model = MyModel(field_name: 'a' * 25
# Default minimum length is 20
assert model.valid?
# Test different length validation
GemName.minimum_field_length = 30
assert_not model.valid?
end
end
Второе утверждение неверно (модель верна). Если я добавлю туда отладчик и проверю, GemName.minimum_field_length выдаст мне 30, указывая, что он изменен, но если я посмотрю на результат MyModel.validators, минимум все равно будет исходным значением по умолчанию, равным 20. Предположительно это связано с тем, что валидаторы создаются один раз. , либо при запуске теста, либо при первом вызове модели (я безуспешно пытался создать новый экземпляр MyModel после изменения конфигурации). Есть ли способ, аналогичный .reset_column_information, обновить валидаторы модели новым значением конфигурации во время теста?
@dbugger: Хороший звонок, я не прикасался к макетам со времен тестирования Java. Какой компонент я бы высмеивал в этом сценарии? Я бы подумал, что это переменная конфигурации, поскольку за это отвечает фреймворк, а не мой код, но как? Я не хочу издеваться над валидатором, я его и тестирую. В любом случае, я не знаю, как подключить макет к соответствующей части цепочки.





Проблема в том, что определение длины minimum в такой проверке
validates_length_of :field_name, minimum: GemName.minimum_field_length
затем он устанавливает минимум только один раз, когда файл читается в первый раз. При изменении GemName.minimum_field_length конфигурация валидатора больше не меняется.
Но когда вместо этого вы инициализируете валидатор с помощью лямбды, лямбда будет оцениваться при каждом вызове валидатора и, следовательно, должна улавливать изменения.
Вместо этого попробуйте это:
validates_length_of :field_name, minimum: -> { GemName.minimum_field_length }
Если вы хотите только убедиться, что минимальная длина поля равна настроенной минимальной длине драгоценного камня, вы можете написать тест, который проверяет, равны ли оба значения, например:
minimum_field_name_length = MyModel.validators_on(:field_name)
.select { |v| v.is_a?(LengthValidator) }
.first
.options[:minimum]
assert_equal minimum_field_name_length, GemName.minimum_field_length
Это работает! Будет ли для этого какая-либо причина, помимо тестирования? Должна ли модель иметь возможность обрабатывать изменения конфигурации в любой момент? Ваш ответ побудил меня попытаться перезагрузить файл модели в тесте, что также решает проблему и кажется лучшим подходом, если лямбда-выражение не используется вне тестовой среды.
В данном случае нет. Потому что GemName.minimum_field_length не изменится, пока сервер работает. Но я могу представить примеры, в которых вы хотите, чтобы проверка была динамической. Например, когда максимальная длина зависит от уровня подписки пользователя. Затем в конфигурацию необходимо загрузить текущую максимальную длину, например, от текущего пользователя.
На самом деле, я бы сказал, что вам вообще не следует тестировать это изменение конфигурации. Проверить, что GemName.minimum_field_length возвращает ожидаемое значение, можно. Тестирование наличия проверки максимальной длины. Но оба метода (конфигурация и валидатор) уже опробованы в гемах. На самом деле нет никакой пользы в повторном тестировании этих методов в вашем приложении, кроме интеграционного теста.
Отлично спасибо! Это начало усложняться, и я почувствовал, что тестирование выходит за рамки моего кода. Мне нужен какой-то тест, чтобы убедиться, что конфигурация используется при проверке, но вместо этого я мог полагаться на удаление класса и перезагрузку файла в тесте, чтобы убедиться, что валидаторы были обновлены конфигурацией, сохраняя при этом лямбда-выражение валидатора. бесплатно, так как это приложение не требует динамических изменений.
@RedBassett Я обновил свой ответ, добавив альтернативный способ убедиться, что валидатор имеет ту же минимальную длину, что и драгоценный камень.
Перед запуском теста имитируйте возвращаемое значение конфигурации.