Как я могу проверить: проверка включения в Rails с использованием RSpec - PullRequest
36 голосов
/ 14 сентября 2011

У меня есть следующая проверка в моей 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 и musta matchers.

EDIT

После некоторого осмотра, который я только обнаружил, это, вероятно, «хороший» способ проверки этого, должен ли что-то для этого предоставить, и любой, кто в этом нуждается, может написать для него свой собственный сопоставитель (и, вероятно, отправит проект). Некоторые ссылки на обсуждения, которые могут быть интересны:

  • Ссылки, которые указывают на вышеуказанное. Ссылка 1 , Ссылка 2

  • should_ensure_value_in_range Этот пример близок к тому, что можно использовать, но принимает только диапазоны, а не список значений. Пользовательское сопоставление может быть основано на этом.

Ответы [ 3 ]

61 голосов
/ 06 августа 2012

Использовать musta_matchers

В последних версиях shoulda-matchers (по крайней мере, начиная с v2.7.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]) }
24 голосов
/ 18 октября 2011

Если у вас есть больше элементов для проверки, чем логическое значение 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
1 голос
/ 22 сентября 2011

Я нашел одно специальное средство сравнения musta (в одном из проектов, над которым я работал), которое пытается приблизиться, чтобы проверить что-то вроде этого:

Примеры:

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 }

Соответствующеепытается гарантировать, что есть ограничение БД, которое разрывается, когда он пытается сохранить его. Я попытаюсь раскрыть суть идеи.Спички?реализация делает что-то вроде:

  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.

...