Тест Ruby on Rails – сброс/обновление валидаторов?

Я пишу тесты для 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 26.02.2024 04:06

@dbugger: Хороший звонок, я не прикасался к макетам со времен тестирования Java. Какой компонент я бы высмеивал в этом сценарии? Я бы подумал, что это переменная конфигурации, поскольку за это отвечает фреймворк, а не мой код, но как? Я не хочу издеваться над валидатором, я его и тестирую. В любом случае, я не знаю, как подключить макет к соответствующей части цепочки.

RedBassett 26.02.2024 07:25
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что определение длины 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

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

RedBassett 26.02.2024 18:02

В данном случае нет. Потому что GemName.minimum_field_length не изменится, пока сервер работает. Но я могу представить примеры, в которых вы хотите, чтобы проверка была динамической. Например, когда максимальная длина зависит от уровня подписки пользователя. Затем в конфигурацию необходимо загрузить текущую максимальную длину, например, от текущего пользователя.

spickermann 27.02.2024 06:41

На самом деле, я бы сказал, что вам вообще не следует тестировать это изменение конфигурации. Проверить, что GemName.minimum_field_length возвращает ожидаемое значение, можно. Тестирование наличия проверки максимальной длины. Но оба метода (конфигурация и валидатор) уже опробованы в гемах. На самом деле нет никакой пользы в повторном тестировании этих методов в вашем приложении, кроме интеграционного теста.

spickermann 27.02.2024 06:45

Отлично спасибо! Это начало усложняться, и я почувствовал, что тестирование выходит за рамки моего кода. Мне нужен какой-то тест, чтобы убедиться, что конфигурация используется при проверке, но вместо этого я мог полагаться на удаление класса и перезагрузку файла в тесте, чтобы убедиться, что валидаторы были обновлены конфигурацией, сохраняя при этом лямбда-выражение валидатора. бесплатно, так как это приложение не требует динамических изменений.

RedBassett 27.02.2024 21:20

@RedBassett Я обновил свой ответ, добавив альтернативный способ убедиться, что валидатор имеет ту же минимальную длину, что и драгоценный камень.

spickermann 28.02.2024 08:13

Другие вопросы по теме