问题
I want to create a mock method that calls the underlying method being mocked.
I'm imagining something like the following, but I can't find any documentation about the mock object holding a reference to the object being mocked, which I've denoted as [[wrapped_method_foo]]
below:
from mock import patch
class Foo(object):
def __init__(self, state):
self.state = state
def foo(self, a):
print "real foo", a
return a + self.state
f = Foo(2000)
f.foo(1)
with patch.object(Foo, 'foo', autospec=True) as mock_foo:
def side_effect(self, a):
print "mock foo", a
return mock_foo.[[wrapped_method_foo]](self, a*2)
mock_foo.side_effect = side_effect
f.foo(2)
回答1:
The simplest way is to grab your own reference to the original function before patching. Patching can be done on an individual instance of the class:
original_foo = f.foo
with patch.object(f, 'foo') as mock_foo:
def side_effect(a):
print "mock foo", a
return original_foo(a*2)
mock_foo.side_effect = side_effect
f.foo(2)
...or by patching the unbound method on the class:
original_foo = Foo.foo
with patch.object(Foo, 'foo', autospec=True) as mock_foo:
def side_effect(self, a):
print "mock foo", a
return original_foo(self, a*2)
mock_foo.side_effect = side_effect
f.foo(3)
回答2:
patch objects have an undocumented temp_original
attribute that you can use.
Here is what I usually do in that case:
from __future__ import print_function
import mock
class Foo(object):
def __init__(self, state):
self.state = state
def foo(self, a):
print("real foo", a)
return a + self.state
f = Foo(2000)
f.foo(1)
fake_foo = mock.patch.object(Foo, 'foo', autospec=True)
# def side_effect(*args, **kwargs): # generic version
def side_effect(self, a):
print("mock foo", a)
return fake_foo.temp_original(self, a*2)
with fake_foo as mock_foo:
mock_foo.side_effect = side_effect
assert f.foo(2) == 2004
I'm using this when I only use mock to assert that functions where called during tests
来源:https://stackoverflow.com/questions/30719735/how-to-call-mocked-method-in-python-mock