4

I'm trying to write a spec for a really long time.

I need to test this:

expect(Foo).to receive(:bar).with(some_args)

and everything works just fine if Foo receives bar only once. But it will receive bar several times for sure so that the string above fails with

#<Foo (class)> received :bar with unexpected arguments

on those calls.

How can I test that Foo receives bar with the exact arguments I need and ignore other cases?

Ngoral
  • 4,215
  • 2
  • 20
  • 37

1 Answers1

1

What about using allow(Foo).to receive(:bar).and_call_original?

For example, these tests will successfully pass:

class Foo
  def boo(b)
    b
  end
end

describe Foo do
  let(:a) { Foo.new }

  before do
    allow(a).to receive(:boo).and_call_original
  end

  it do
    expect(a).to receive(:boo).with(2)

    expect(a.boo(1)).to eq 1
    expect(a.boo(2)).to eq 2
    expect(a.boo(3)).to eq 3
  end
end

If you add expect(a).to receive(:boo).with(4) to the block, the test will fail. It seems like what you're looking for, right?

Igor Drozdov
  • 14,690
  • 5
  • 37
  • 53
  • That's it. I thought I tried it and that didn't work out. But I tried once again now and it all done, thanx! (I must have forgotten to save changes when tried it on my own, cause I had exact this line commented out:) ) – Ngoral Jul 26 '17 at 20:56
  • Looks like this doesn't work anymore, and I haven't found anything more recent about it. How can I find information about the limitations or changes to this? – ShadSterling Jul 28 '22 at 18:08
  • @ShadSterling which version of rspec do you use? I guess it should still work – Ngoral Aug 08 '22 at 12:36
  • @Ngoral Gemfile.lock has spec-core (3.11.0). I was adapting the spec for an old class to test its replacement and the error I thought was this was fixed as a side effect of fixing other failing tests, so unfortunately I'm not sure what the actual problem was – ShadSterling Aug 10 '22 at 20:22