[Ruby] Check method call arguments in blocks with RSpec

less than 1 minute read

RSpec expect(foo).to receive(:bar).with(...) allows argument checking in several ways, but there are quite a few cases where you want to verify with a block.

You can pass a matcher to with, so you can define a custom matcher. In the example below, only certain attributes of Struct are validated

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

In addition, since the argument verification by with is performed for each argument, in the case of a method that takes multiple arguments, it is necessary to pass a matcher for each argument.

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

Tags: ,

Updated: