41

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マッチャーを使用しています。

編集

私が見つけたいくつかの周りを見た後、これはおそらくこれをテストする「OK」の方法です、shouldaはこれに何も提供せず、それを必要とする人は誰でもそれのために独自のカスタムマッチャーを書くことができます(そしておそらくそれをプロジェクトに貢献してください) 。興味をそそられるかもしれない議論へのいくつかのリンク:

  • 上記を示すリンク。リンク1リンク2

  • should_ensure_value_in_rangeこれは使用できるものに近づいていますが、範囲のみを受け入れ、値のリストは受け入れません。カスタムマッチャーはこれに基づくことができます。

4

3 に答える 3

72

shoulda_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]) }
于 2012-08-06T15:58:40.010 に答える
25

ブール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
于 2011-10-18T03:59:49.487 に答える
1

私は(私が取り組んでいたプロジェクトの1つで)次のようなものをテストするために近づこうとする1つのカスタムshouldaマッチャーを見つけました:

例:

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.saveRailsの検証を爆発させると、例外文字列に実際の例外エラーメッセージに近いものが含まれている場合にfalseを返すことができます。

:inclusionこれがプロジェクトに貢献するには完璧にはほど遠いことはわかっていますが、実際に多くの検証をテストしたい場合は、カスタムマッチャーとしてプロジェクトに追加することは悪い考えではないかもしれません。

于 2011-09-22T03:04:37.370 に答える