You want cross mock ordering! I've wanted this in RSpec in the past as well. The only ruby-based mocking library I know of that does this is Hardmock. It looks like its RDoc now has instructions for it to work with RSpec:<br>
<br><a href="http://hardmock.rubyforge.org/">http://hardmock.rubyforge.org/</a><br><br>Zach<br><br><div class="gmail_quote">On Sun, Jul 13, 2008 at 11:35 AM, Sven Fuchs <<a href="mailto:svenfuchs@artweb-design.de">svenfuchs@artweb-design.de</a>> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div><div></div><div class="Wj3C7c">On 13.07.2008, at 17:01, Sven Fuchs wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
On 13.07.2008, at 16:41, David Chelimsky wrote:<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
On Sun, Jul 13, 2008 at 9:32 AM, Pat Maddox <<a href="mailto:pergesu@gmail.com" target="_blank">pergesu@gmail.com</a>> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
On Sun, Jul 13, 2008 at 9:49 AM, Sven Fuchs <<a href="mailto:svenfuchs@artweb-design.de" target="_blank">svenfuchs@artweb-design.de</a>> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I've been wondering how to expect arbitrary methods being called in a<br>
particular order. The RSpec documentation for expecting method calls on mock<br>
objects mentions that it is possible to pass a block to #should_receive, but<br>
does not mention that it can be used to track the method call order pretty<br>
easily:<br>
<br>
<a href="http://www.artweb-design.de/2008/7/13/expecting-arbitrary-method-calls-in-a-particular-order-in-rspec" target="_blank">http://www.artweb-design.de/2008/7/13/expecting-arbitrary-method-calls-in-a-particular-order-in-rspec</a><br>
<br>
Is there a better way of doing this?<br>
<br>
If not, do you think it would make sense to add this to the RSpec docs?<br>
<a href="http://rspec.info/documentation/mocks/message_expectations.html" target="_blank">http://rspec.info/documentation/mocks/message_expectations.html</a><br>
</blockquote>
<br>
Hey Sven,<br>
<br>
Mock objects have an optional notion of ordering. Check out the following spec:<br>
<br>
describe "a mock object" do<br>
it "should expect ordered messages" do<br>
foo = mock("ordered mock")<br>
foo.should_receive(:first).ordered<br>
foo.should_receive(:second).ordered<br>
foo.should_receive(:third).ordered<br>
<br>
foo.first<br>
foo.second<br>
foo.third<br>
end<br>
end<br>
<br>
Changing the order in which they're called will raise an ExpectationNotMetError.<br>
</blockquote>
<br>
Sven, FYI - this is explained on the page you mentioned:<br>
<a href="http://rspec.info/documentation/mocks/message_expectations.html" target="_blank">http://rspec.info/documentation/mocks/message_expectations.html</a><br>
</blockquote>
<br>
Hey guys, thanks for the quick answers :)<br>
<br>
Maybe I was not clear enough about what I wanted to spec. Or I actually do not understand what #ordered does.<br>
<br>
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:<br>
<br>
filter_1 = mock('filter_1')<br>
filter_2 = mock('filter_2')<br>
filter_chain << filter_1<br>
filter_chain << filter_2<br>
<br>
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:<br>
<br>
filter_chain.run<br>
methods_called_on_individual_filters.should == ['filter_1#run', 'filter_2#run'] # pseudo-code<br>
<br>
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")<br>
<br>
Am I missing something?<br>
</blockquote>
<br></div></div>
Maybe it's bit more clear this way:<br>
<br>
class Chain < Array<br>
def run<br>
each{|object| object.run}<br>
end<br>
end<br>
<br>
describe "Expecting the order of methods being called on arbitrary objects" do<br>
it "works" do<br>
first = mock('first')<br>
second = mock('second')<br>
<br>
chain = Chain.new<br>
chain << first<br>
chain << second<br>
<br>
second.should_receive(:run).ordered<br>
first.should_receive(:run).ordered<br>
chain.run<br>
end<br>
end<br>
<br>
This passes, of course.<br>
<br>
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<div><div></div><div class="Wj3C7c"><br>
<br>
<br>
--<br>
sven fuchs <a href="mailto:svenfuchs@artweb-design.de" target="_blank">svenfuchs@artweb-design.de</a><br>
artweb design <a href="http://www.artweb-design.de" target="_blank">http://www.artweb-design.de</a><br>
grünberger 65 + 49 (0) 30 - 47 98 69 96 (phone)<br>
d-10245 berlin + 49 (0) 171 - 35 20 38 4 (mobile)<br>
<br>
<br>
<br>
_______________________________________________<br>
rspec-users mailing list<br>
<a href="mailto:rspec-users@rubyforge.org" target="_blank">rspec-users@rubyforge.org</a><br>
<a href="http://rubyforge.org/mailman/listinfo/rspec-users" target="_blank">http://rubyforge.org/mailman/listinfo/rspec-users</a><br>
</div></div></blockquote></div><br><br clear="all"><br>-- <br>Zach Dennis<br><a href="http://www.continuousthinking.com">http://www.continuousthinking.com</a>