0

子属性の数を検証するカスタム アクションがあります。これを親のモデルに入れました:

class Location < ActiveRecord::Base
  has_many :blacklisted
  accepts_nested_attributes_for :blacklisted, :reject_if => lambda { |a| a[:mac].blank? }, :allow_destroy => true  
  ...
  validate :check_blacklisted_clients_count

  private

  def check_blacklisted_clients_count
    if self.blacklisted.reject(&:marked_for_destruction?).count > 25
      self.errors.add :base, "No more than 25 blacklisted clients allowed per location."
    end
  end

ブラウザから追加すると問題なく動作しますが、rspecでこれをテストしようとしていますが、失敗することはありません(または、どのように見ても合格です)。

  it "should not allow 26 blacklisted macs", :focus => true do 
    loc = FactoryGirl.create(:location_full)
    25.times do
      loc.blacklisted.create(mac: '00:22:33:44:55:66')
    end
    loc.blacklisted.create(mac: '00:22:33:44:55:66')
    puts loc.blacklisted.count
    .........

  end

(実際にはまだ何もテストしていないことはわかっています.25個しか作成されていないことを確認したかっただけです)。

これは、blacklisted.rb モデルに検証がないためだと思います。

rspec を取得してこの検証をテストするにはどうすればよいですか?

4

1 に答える 1

1

最も簡単な方法は、ブラックリストに登録された MAC を 25 未満追加する仕様と、25 を超える MAC を追加する仕様を作成し、前者が有効で後者が無効であることをテストすることです。

仕様のランタイムについてどう思うかによって、うまくいくかもしれません。テストが遅すぎる場合は、スタブを使用することをお勧めします。例えば:

let(:location) { Location.new }

it "should be invalid with more than 25 blacklisted MACs" do
  location.stub_chain(:blacklisted, :reject, :count) { 26 }
  location.should be_invalid
  location.errors(:base).should include("No more than 25 blacklisted clients allowed per location.")
end

スタブの使用には欠点があります。仕様が脆弱になりやすく、実装と密接に結び付きすぎる可能性があります。一方、25,000 個の MAC をチェックしている場合、実際のオブジェクトを使用したテストは現実的ではない可能性があります。

于 2013-02-09T02:47:52.003 に答える