[rspec-users] Expecting arbitrary method calls in a particular order

Sven Fuchs svenfuchs at artweb-design.de
Sun Jul 13 11:35:58 EDT 2008


On 13.07.2008, at 17:01, Sven Fuchs wrote:
>
> On 13.07.2008, at 16:41, David Chelimsky wrote:
>
>> On Sun, Jul 13, 2008 at 9:32 AM, Pat Maddox <pergesu at gmail.com>  
>> wrote:
>>> On Sun, Jul 13, 2008 at 9:49 AM, Sven Fuchs <svenfuchs at artweb-design.de 
>>> > wrote:
>>>> I've been wondering how to expect arbitrary methods being called  
>>>> in a
>>>> particular order. The RSpec documentation for expecting method  
>>>> calls on mock
>>>> objects mentions that it is possible to pass a block to  
>>>> #should_receive, but
>>>> does not mention that it can be used to track the method call  
>>>> order pretty
>>>> easily:
>>>>
>>>> http://www.artweb-design.de/2008/7/13/expecting-arbitrary-method-calls-in-a-particular-order-in-rspec
>>>>
>>>> Is there a better way of doing this?
>>>>
>>>> If not, do you think it would make sense to add this to the RSpec  
>>>> docs?
>>>> http://rspec.info/documentation/mocks/message_expectations.html
>>>
>>> Hey Sven,
>>>
>>> Mock objects have an optional notion of ordering.  Check out the  
>>> following spec:
>>>
>>> describe "a mock object" do
>>> it "should expect ordered messages" do
>>>  foo = mock("ordered mock")
>>>  foo.should_receive(:first).ordered
>>>  foo.should_receive(:second).ordered
>>>  foo.should_receive(:third).ordered
>>>
>>>  foo.first
>>>  foo.second
>>>  foo.third
>>> end
>>> end
>>>
>>> Changing the order in which they're called will raise an  
>>> ExpectationNotMetError.
>>
>> Sven, FYI - this is explained on the page you mentioned:
>> http://rspec.info/documentation/mocks/message_expectations.html
>
> Hey guys, thanks for the quick answers :)
>
> Maybe I was not clear enough about what I wanted to spec. Or I  
> actually do not understand what #ordered does.
>
> In Pat's spec above the methods #first, #second and #third are  
> called on the same object foo and the spec defines the order. That's  
> kind of the opposite of my usecase. I wanted to specify that the a  
> method #run (or whatever) is called on *different* objects in a  
> particular order. Like:
>
> filter_1 = mock('filter_1')
> filter_2 = mock('filter_2')
> filter_chain << filter_1
> filter_chain << filter_2
>
> Now, when the filter_chain is run I want to expect that the filters  
> are run in the order they were added to the chain:
>
> filter_chain.run
> methods_called_on_individual_filters.should == ['filter_1#run',  
> 'filter_2#run'] # pseudo-code
>
> If that's possible somehow with should_receive(:run).ordered than at  
> least it's not very clear from that docs page which only talks about  
> expecting the order of methods being called on the same mock, not on  
> different mocks. ("There are times when you want to specify the  
> order of messages sent to *a* mock")
>
> Am I missing something?

Maybe it's bit more clear this way:

class Chain < Array
   def run
     each{|object| object.run}
   end
end

describe "Expecting the order of methods being called on arbitrary  
objects" do
   it "works" do
     first = mock('first')
     second = mock('second')

     chain = Chain.new
     chain << first
     chain << second

     second.should_receive(:run).ordered
     first.should_receive(:run).ordered
     chain.run
   end
end

This passes, of course.

I'd want to to specify that first#run is run first and second#run is  
run second though and I think I can't do that with  
should_receive.ordered


--
sven fuchs			svenfuchs at artweb-design.de
artweb design		http://www.artweb-design.de
grünberger 65		+ 49 (0) 30 - 47 98 69 96 (phone)
d-10245 berlin		+ 49 (0) 171 - 35 20 38 4 (mobile)





More information about the rspec-users mailing list