我有一个自定义操作来验证子属性的数量。我把它放在父母的模型中:
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测试此验证?
答案 0 :(得分: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,那么使用真实对象进行测试可能并不可行。