Как я могу проверить: проверка включения в Rails с помощью RSpec
У меня есть следующая проверка в моем ActiveRecord.
validates :active, :inclusion => {:in => ['Y', 'N']}
Я использую следующее, чтобы проверить мои проверки модели.
should_not allow_value('A').for(:active)
should allow_value('Y').for(:active)
should allow_value('N').for(:active)
Есть ли более чистые и более сквозные способы тестирования? В настоящее время я использую RSpec2 и сокеты.
ИЗМЕНИТЬ
После того, как я огляделся, я обнаружил, что это, вероятно, "нормально" способ проверить это, shoulda не предоставляет ничего для этого, и любой, кто этого требует, может написать свой собственный собственный макет для него (и, вероятно, внести его обратно в проект). Некоторые ссылки на дискуссии, которые могут быть интересными:
-
Ссылки, которые указывают на вышеизложенное. Ссылка 1, Ссылка 2
-
should_ensure_value_in_range
Это приближается к тому, что можно использовать, но принимает только диапазоны, а не список значений. Пользовательский сопоставление может быть основан на этом.
Ответы
Ответ 1
Использовать toa_matchers
В последних версиях shoulda-matchers
(по крайней мере, начиная с версии 2.2.0) вы можете:
expect(subject).to validate_inclusion_of(:active).in_array(%w[Y N])
Это проверяет, что массив допустимых значений в валидации точно соответствует этой спецификации.
В более ранних версиях >= v1.4, shoulda_matchers
поддерживает этот синтаксис:
it {should ensure_inclusion_of(:active).in_array(%w[Y N]) }
Ответ 2
Если у вас есть больше элементов для проверки, чем логическое значение Y/N, вы также можете попробовать.
it "should allow valid values" do
%w(item1 item2 item3 item4).each do |v|
should allow_value(v).for(:field)
end
end
it { should_not allow_value("other").for(:role) }
Вы также можете заменить %w()
на константу, определенную в вашей модели, чтобы она проверяла, что разрешены только постоянные значения.
CONSTANT = %w[item1 item2 item3 item4]
validates :field, :inclusion => CONSTANT
Тогда тест:
it "should allow valid values" do
Model::CONSTANT.each do |v|
should allow_value(v).for(:field)
end
end
Ответ 3
Я нашел один пользовательский помощник по назначению (в одном из проектов, над которым я работал), который пытается приблизиться, чтобы проверить что-то вроде этого:
Примеры:
it { should validate_inclusion_check_constraint_on :status, :allowed_values => %w(Open Resolved Closed) }
it { should validate_inclusion_check_constraint_on :age, :allowed_values => 0..100 }
Соединитель пытается убедиться, что существует ограничение DB, которое взрывается, когда оно пытается его сохранить. Я попытаюсь дать суть идеи. Матчи? реализация делает что-то вроде:
begin
@allowed_values.each do |value|
@subject.send("#{@attribute}=", value)
@subject.save(:validate => false)
end
rescue ::ActiveRecord::StatementInvalid => e
# Returns false if the exception message contains a string matching the error throw by SQL db
end
Я думаю, если мы немного изменим сказанное выше, чтобы сказать @subject.save
, и пусть проверка правильности Rails взорвется, мы можем вернуть false, когда строка исключения содержит что-то, что близко соответствует реальному сообщению об ошибке.
Я знаю, что это далеко не идеальный вариант, чтобы внести свой вклад в проект, но, возможно, неплохо было бы добавить в свой проект как пользовательский матчи, если вы действительно хотите проверить проверку валидации :inclusion
.