Jak Mogę przetestować: Walidacja włączenia w Rails przy użyciu RSpec

Mam następujące potwierdzenie w moim ActiveRecord.

validates :active, :inclusion => {:in => ['Y', 'N']}

Używam następujących do testowania walidacji mojego modelu.

should_not allow_value('A').for(:active)
should allow_value('Y').for(:active)
should allow_value('N').for(:active)

Czy Jest jakiś sposób na testowanie tego? Obecnie używam RSpec2 i shoulda matchers.

EDIT

Po pewnym rozglądaniu się tylko znalazłem, to prawdopodobnie " ok " sposób testowania tego, shoulda nie zapewnia nic do tego i każdy, kto tego wymaga, może napisać własny niestandardowy matcher dla niego.(Oraz prawdopodobnie przyczynić się do tego projektu). Niektóre linki do dyskusji, które mogą być interesujące:

  • Linki wskazujące na powyższe . Link 1 , Link 2

  • should_ensure_value_in_range ten jest zbliżony do tego, co można użyć, ale akceptuje tylko zakresy, a nie listę wartości. Niestandardowy matcher może być oparty na tym.

Author: jake, 2011-09-14

3 answers

Użyj shoulda_matchers

W najnowszych wersjach shoulda-matchers (przynajmniej od v2.7.0), można zrobić:

expect(subject).to validate_inclusion_of(:active).in_array(%w[Y N])

To sprawdza, czy tablica dopuszczalnych wartości w walidacji dokładnie odpowiada tej specyfikacji.

We wcześniejszych wersjach, > = v1. 4, shoulda_matchers obsługuje tę składnię:

it {should ensure_inclusion_of(:active).in_array(%w[Y N]) }
 57
Author: Nathan Long,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-25 19:46:14

Jeśli masz więcej elementów do przetestowania niż logiczny Y / N, możesz również spróbować.

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) }

Można również zastąpić %w() stałą zdefiniowaną w modelu, aby sprawdzić, czy dozwolone są tylko wartości stałe.

CONSTANT = %w[item1 item2 item3 item4]
validates :field, :inclusion => CONSTANT

Następnie test:

it "should allow valid values" do
  Model::CONSTANT.each do |v|
    should allow_value(v).for(:field)
  end
end
 23
Author: nmott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-18 03:59:49

Znalazłem jeden custom shoulda matcher (w jednym z projektów, nad którymi pracowałem), który próbuje zbliżyć się do testowania czegoś takiego:

Przykłady:

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 }

Matcher stara się zapewnić, że istnieje ograniczenie DB, które wybucha, gdy próbuje go zapisać.Postaram się przekazać istotę idei. Zapałki? implementacja robi coś takiego:

  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

Myślę, że jeśli nieco zmienimy powyższe na @subject.save i pozwolimy walidacji Rails wybuchnąć, możemy powrócić false, gdy łańcuch WYJĄTKÓW zawiera coś, co pasuje do rzeczywistego Komunikatu o błędzie wyjątku.

Wiem, że to nie jest idealne, aby przyczynić się do projektu, ale myślę, że nie jest złym pomysłem, aby dodać do swojego projektu jako niestandardowy matcher, jeśli naprawdę chcesz przetestować wiele walidacji {3]}.

 1
Author: jake,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-22 03:04:37