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