我正在尝试使用RSpec在RoR中为我的测试创建自定义匹配器。
define :be_accessible do |attributes|
attributes = attributes.is_a?(Array) ? attributes : [attributes]
attributes.each do |attribute|
match do |response|
response.class.accessible_attributes.include?(attribute)
end
description { "#{attribute} should be accessible" }
failure_message_for_should { "#{attribute} should be accessible" }
failure_message_for_should_not { "#{attribute} should not be accessible" }
end
end
我希望能够在我的测试中写出如下内容:
...
should be_accessible(:name, :surname, :description)
...
但是使用上面定义的匹配器,我必须传递一个符号数组而不是用逗号分隔的符号,否则测试只检查第一个符号。
有什么想法吗?
答案 0 :(得分:4)
我以这种方式工作:
RSpec::Matchers.define :be_accessible do |*attributes|
match do |response|
description { "#{attributes.inspect} be accessible" }
attributes.each do |attribute|
failure_message_for_should { "#{attribute} should be accessible" }
failure_message_for_should_not { "#{attribute} should not be accessible" }
break false unless response.class.accessible_attributes.include?(attribute)
end
end
end
我颠倒了match
和each
循环。我认为这是Rspec预期的方式,因为match
方法的块是由Rspec抽象匹配器执行的块(我猜)。
通过使用|*attributes|
定义块,它会获取参数列表并将其转换为Array
。
所以调用should be_accessible(:name, :surname, :description)
即可。
顺便说一下,如果你只想检查属性是否存在,那就简单了
should respond_to(:name, :surname, :description)
也可以。但它看起来并不适合大规模的分配方面。