Expecting arbitrary method calls in a particular order in RSpec
posted: July 13th, 2008 · by: Sven
For a spam protection feature in a project I’m currently working on I started out specifying the behaviour of a filter chain that I was planning to implement. Specifically, I wanted to specify that the filter chain would call the filters in the expected order.
Looking at the RSpec documentation for expecting method calls on mock objects I didn’t found this usecase mentioned at first. It turns out to be pretty easy with RSpec mocks though.
#should_receive takes a block that (according to the documentation) is meant to be used to compute return values. This block is called within the specification’s scope so it can be used to track the method call order.
My initial spec looks like this (simplified for clarity):
it "runs the filters in the correct order" do
log = []
@default.should_receive(:run){ log << :default }
@akismet.should_receive(:run){ log << :akismet }
@defensio.should_receive(:run){ log << :defensio }
@chain.run
log.should == [:default, :akismet, :defensio]
end
Update
After some discussion on the RSpec users mailinglist Ashley Moran pointed out a more elegant solution to this which also uses the should_receive block:
it "runs the filters in the correct order" do
@default.should_receive(:run) do
@akismet.should_receive(:run) do
@defensio.should_receive(:run)
end
end
@chain.run
end
Thanks :)
wicktor said November 26th, 2008 at 05:05 PM ¶
That instructions were very helpful.
jgeiger said January 23rd, 2009 at 09:32 PM ¶
Actually if you go down a bit on the RSpec documentation for expecting method calls on mock objects page, there is a way to set the order.