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

最直接的方法是编写一个添加少于 25 个列入黑名单的 MAC 的规范,以及另一个添加超过 25 个的规范,并测试前者有效,后者无效。

根据您对规范运行时的感觉,这可能会很好。如果测试太慢,您可能需要使用存根。例如:

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 回答