[rspec-users] Surprising mock behavior

Zach Dennis zach.dennis at gmail.com
Sun Oct 19 10:40:37 EDT 2008


On Sun, Oct 19, 2008 at 1:34 AM, Mark Thomson <mark.thomson at ieee.org> wrote:
>
> Zach Dennis wrote:
>>
>> I'm top posting... I wish I could inline post, but you provided a lot
>> of generalizations for how you think things are working on your code,
>> but you don't actually post concrete code (the should_receive and
>> should_not_receive case you mentioned that wasn't acting like you'd
>> expect). Perhaps this will help:
>>
>> * Mocks are not ordered by default.
>>
>
> Yeah that's consistent with what I'm seeing. I mentioned ordering only
> because it was one of the things that came up in my mind as I was searching
> for a way to understand the different behaviors I was seeing.
>
>> * If you want ordered message expectations on a mock you have to
>> explicitly tell them to be ordered.
>>
>
> Really, you can do that? I'm curious about how.

Checkout http://rspec.info/documentation/mocks/message_expectations.html

And look at the Ordering section.

>
>> * You cannot enforce ordering across mocks.
>>
>> So without explicitly ordering, message expectations can be fulfilled
>> in any order. For example the below will pass even though the
>> expectation for 1 and 3 does not match the order in when the bar
>> method is called:
>>
>>    file = Object.new
>>    file.should_receive(:bar).with("1")
>>    file.should_receive(:bar).with("3")
>>
>>    file.bar "3"
>>    file.bar "1"
>>
>>
>
> Ok got that.
>
>> Once a message expectation is fulfilled, if the object receives
>> another message matching that expectation it will force it to fail.
>> For example, the following would fail even though there are two
>> expectations for "bar" to be called with "1", which match the two
>> calls to file.bar:
>>
>>    file = Object.new
>>    file.should_receive(:bar).with("1")
>>    file.should_receive(:bar).with("1")
>>
>>    file.bar "1"
>>    file.bar "1"
>>
>
> This one kind of surprises me, but I understand your point.
>
>> Using should_not_receive and should_receive on the same message gets
>> tricky, because you can trick yourself into thinking the thing is
>> passing when it shouldn't be. For example the below will fail because
>> even though you call file.bar with "2", that matches the expectation
>> that file.bar should not be called with "3":
>>
>>    file = Object.new
>>    file.should_receive(:bar).with("1")
>>    file.should_not_receive(:bar).with("3")
>>
>>    file.bar "1"
>>    file.bar "2"
>>
>
> Did you mean to say that will *not* fail since "2" will match "not 3"?

Yes, that's what I meant.

-- 
Zach Dennis
http://www.continuousthinking.com
http://www.mutuallyhuman.com


More information about the rspec-users mailing list