views:

156

answers:

2

I currently have some expectations set up on a mock with consecutive calls:

The spec:

@my_mock = mock("a_mock")
@options1 = {:some => "option"}
@options2 = {:some_other => "option"}
@first_param = mock("first_param")

@my_mock.should_receive(:a_message).with(@first_param, @options1)
@my_mock.should_receive(:a_message).with(@first_param, @options2)

However, i get the following:

Mock "a_mock" received :a_message with unexpected arguments
  expected: (#<Spec::Mocks::Mock:0x81b8ca3c @name="first_param"{:some => "option"})
   got: (#<Spec::Mocks::Mock:0x81b8ca3c @name="first_param">, {:some_other => "option"})

When I debug this, the first expectation IS getting called. Do I have to specify anything else before I can expect consecutive calls with the same message but differing parameters?

A: 

Try creating your mock as a null object to ignore extra method calls. Each of your expectations will still have to be met, but they won't step on each other.

@my_mock = mock("a_mock").as_null_object

This follows the Null Object pattern, in which any extraneous messages are just ignored. It is useful with mocks when you want to make sure a method gets called with certain parameters, but you don't care if it is called with other parameters or if any other methods get called.

Baldu
This does help. However I'm not sure what this is doing. Can you explain?
Chris Rittersdorf
I updated my answer with a little extra info about null objects. I'm not a pattern or testing expert, but I hope it helps a bit.
Baldu
A: 

if it's difficult to test, rewrite your implementation.

fernyb
Unfortunately, the calls that I am putting these expectations are part of an external library. So, I'm kind of stuck with using that. Currently there are no real alternatives to this.
Chris Rittersdorf