Search code examples
rubytestingrspecrspec3

On method called on double, expectations about the argument


I have created a double, I am executing code that will call it with a method and a huge hash as a argument, I want to verify one key of the argument, and then return a specific hash.

This is what I am doing

before :each do
  allow(@my_double).to receive(:do_stuff).and_return({stuff: 42})
end
it "can do stuff" do
  expect(@my_double).to receive(:do_stuff) do  |arg|
    expect(arg).to be_a(Hash)
    expect(arg[:my_arg]).to eq(3)
  end
  TestObject.stuff() # will invoke do_stuff on the double
end

What happens is, the first time do_stuff is called, it returns true which is the result of the receive block, but on subsequent calls(tested in pry) it correctly returns {stuff: 42} but since the first call is wrong, my method exceptions out when it tries to call[:stuff] on the return.

I am trying to let allow define the behaviour of the double so I don't want to put the return in the bottom of the expect.. but is there any way around it?


Solution

  • Figured out the answer is to use an as yet undocumented argument matcher hash_including much like my first comment

    expect(@my_double).to receive(:do_stuff).with(hash_including(my_arg: 3))
    

    This works nicely.