次の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
両方のレベルで。シンプルなものが不足しています。
回答:
回答№1は1Neil 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
回答№2の場合は0
そのようなマッチャーをrspecに追加することについての議論がありました。あなたのブロックの質問についてはわかりませんが、エレガントではない見た目でこのテストを表すことができます:
foo.bars.any?{|bar| bar.id == 42}.should be_true
おそらく、カスタムマッチャーを作成するよりも簡単で、テストが次のようなものであれば読みやすいはずです。 it "should include at least one foo matching the id"
回答№3の場合は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