[rspec-users] Specifying that code is called in a block

Ashley Moran ashley.moran at codeweavers.net
Tue Mar 6 09:13:57 EST 2007

Hey Lugovoi

Not tried that yet but I like the look of it.  You'd have to stub out  
ActiveRecord::Base.transaction to make it work (meddling with another  
API call!!! it's starting to grate on me how often this is necessary)  
though which will surely break transactional fixtures?  It just  
occured to me that I haven't used transactional fixtures - I got  
confused why some specs were failing, although a recent post made me  
suspect my test database was just full of crap, and wrote a method to  
SQL delete the contents table by table.  So I never noticed the  
fallout from stubbing ActiveRecord::Base.transaction, if there was any.

I get the feeling this is something that could be generalised  
though.  I'm just reading the paper Mock Roles, not Objects by four  
of the ThoughtWorks crew.  Apparently jMock supports ordering of  
methods across mocks.  I don't know if this is something that's been  
considered for RSpec.


On 2 Mar 2007, at 17:41, Lugovoi Nikolai wrote:

> What about such specification?
>   specify "cow, dog and duck must be saved in the same transaction" do
>     $log.clear
>     @connection.stub!(:begin_db_transaction).and_return {
> $log.record("BEGIN"); nil }
>     @connection.stub!(:commit_db_transaction).and_return {
> $log.record("COMMIT"); nil }
>     @cow.stub!(:save!).and_return  {$log.record("COW SAVE"); true}
>     @dog.stub!(:save!).and_return  {$log.record("DOG SAVE"); true}
>     @duck.stub!(:save!).and_return {$log.record("DUCK SAVE"); true}
>     @tested_object.exec_method_about_cow_dog_and_duck
>     txn_intervals = %w(COW DUCK DOG).collect do |beast|
>       [ $log.find("BEGIN", :before, "#{beast} SAVE"),
> $log.find("COMMIT", :after, "#{beast} SAVE")]
>     end
>     txn_intervals.each do |range|
>       range[0].should_be kind_of(Time)
>       range[1].should_be kind_of(Time)
>     end
>     txn_intervals.uniq.size.should == 1
>   end
> where $log can be something like:
>     $log = Struct.new(:events, :timestamps).new
>     def $log.clear
>       events = []
>       timestamps = []
>     end
>     def $log.record(what)
>       events << what
>       timestamps << Time.now
>     end
>     def $log.find(what, where, start)
>      # return timestamp of event `what' that is :before or :after
> (where)  event `start'
>     end


Codeweavers Ltd (Registered in England and Wales No. 04092394. VAT  
registration no. 823826816)
Address: Unit 11, Imex Technology Park, ST4 8LJ.     Tel: 0870 443 0888

More information about the rspec-users mailing list