如何创建以下RSpec匹配器?
foo.bars.should incude_at_least_one {|bar| bar.id == 42 }
让我知道如果我重新发明轮子,但我也很想知道如何创建一个自定义匹配器。一些内置的匹配器可以做到,所以它是可能的。我试过这个:
RSpec::Matchers.define :incude_at_least_one do |expected|
match do |actual|
actual.each do |item|
return true if yield(item)
end
false
end
end
我试图在两个方面传递&block
。我错过了一些简单的事情。
答案 0 :(得分:1)
我开始使用Neil Slater的代码,然后开始工作:
class IncludeAtLeastOne
def initialize(&block)
@block = block
end
def matches?(actual)
@actual = actual
@actual.any? {|item| @block.call(item) }
end
def failure_message_for_should
"expected #{@actual.inspect} to include at least one matching item, but it did not"
end
def failure_message_for_should_not
"expected #{@actual.inspect} not to include at least one, but it did"
end
end
def include_at_least_one(&block)
IncludeAtLeastOne.new &block
end
答案 1 :(得分:0)
有关于将这样的匹配器添加到rspec的讨论。我不确定你的阻止问题,但你可以代表这个测试,而不是看起来优雅:
foo.bars.any?{|bar| bar.id == 42}.should be_true
可能比制作自定义匹配器更容易,如果您的测试类似于it "should include at least one foo matching the id"
答案 2 :(得分:0)
RSpec DSL不会这样做,但你可以这样做:
class IncludeAtLeastOne
def matches?(target)
@target = target
@target.any? do |item|
yield( item )
end
end
def failure_message_for_should
"expected #{@target.inspect} to include at least one thing"
end
def failure_message_for_should_not
"expected #{@target.inspect} not to include at least one"
end
end
def include_at_least_one
IncludeAtLeastOne.new
end
describe "foos" do
it "should contain something interesting" do
[1,2,3].should include_at_least_one { |x| x == 1 }
end
end