RSpec の expect(foo).to receive(:bar).with(...)
では引数のチェックがいくつかの方法で可能だが、ブロックで検証したいケースが結構ある。
with には matcher を渡すことができるので、カスタム matcher を定義してやればよい。
下記の例では Struct の特定の attribute のみ検証している
RSpec::Matchers.define :a_valid_argument do
match {|actual| block_arg.call(actual) }
end
it "should call with valid argument" do
jon = Struct.new(:name).new("Jon")
expect($stdout).to receive(:write).with(
a_valid_argument {|a| a.name == "Jon" },
)
$stdout.write(jon)
end
なお、with
による引数の検証は引数ごとに行われるので複数の引数をとるメソッドの場合は、引数ごとに matcher を渡す必要がある。
it "should call with valid arguments" do
jon = Struct.new(:name).new("Jon")
dany = Struct.new(:name).new("Dany")
expect($stdout).to receive(:write).with(
a_valid_argument {|a| a.name == "Jon" },
a_valid_argument {|a| a.name == "Dany" },
)
$stdout.write(jon, dany)
end