Duncan Beevers
2007-Aug-08 20:51 UTC
[mocha-developer] Mocking Time, delegating to original object
In my Unit tests, I run into the all-too-common problem of Time.expects(:now) being called by Benchmark before the method is unmocked. Instead of messing around with the teardown order, I decided to modify the Expectation with a new method, .stops_mocking. Here are the changes I use, including a few monkey patches to push relevant objects down to where I want them, all wrapped up in a big ugly file. module Mocha class Mock def expects(method_name_or_hash, backtrace = nil, stub_method = nil) @stub_method = stub_method if method_name_or_hash.is_a?(Hash) then method_name_or_hash.each do |method_name, return_value| add_expectation(Expectation.new(self, method_name, backtrace).returns(return_value)) end else add_expectation(Expectation.new(self, method_name_or_hash, backtrace)) end end def stubs(method_name_or_hash, backtrace = nil, stub_method = nil) @stub_method = stub_method if method_name_or_hash.is_a?(Hash) then method_name_or_hash.each do |method_name, return_value| add_expectation(Stub.new(self, method_name, backtrace).returns(return_value)) end else add_expectation(Stub.new(self, method_name_or_hash, backtrace)) end end end class Expectation def delegates @return_values += ReturnValues.new(Delegator.new(self)) end alias :stops_mocking :delegates alias :stops_stubbing :delegates end class Delegator def initialize expectation @expectation = expectation end def evaluate @expectation.mock.stub_method.stubbee.send(@expectation.mock.stub_method.hidden_method) end end end class Object def expects(symbol) method = stubba_method.new(stubba_object, symbol) $stubba.stub(method) mocha.expects(symbol, caller, method) end def stubs(symbol) method = stubba_method.new(stubba_object, symbol) $stubba.stub(method) mocha.stubs(symbol, caller, method) end end Haven''t tested this with anything other than Time.now, but thought I''d solicit the general opinion about this behavior. Usage is: Time.expects(:now).returns(mock_time).then.stops_mocking