问题
class A():
def tmp(self):
print("hi")
def b(a):
a.tmp()
To check if tmp method is called in b, the recommended way is
a = A()
a.tmp = MagicMock()
b(a)
a.tmp.assert_called()
But tmp here is being mocked away and is not resulting in a "hi"
getting printed.
I would want my unit test to check if method tmp is called without mocking it away.
Is this possible?
I know this is not a standard thing to expect when writing unitests. But my use case (which is bit tricky) requires this.
回答1:
You can set the Mock.side_effect to be the original method.
from unittest.mock import MagicMock
class A():
def tmp(self):
print("hi")
def b(a):
a.tmp()
a = A()
a.tmp = MagicMock(side_effect=a.tmp)
b(a)
a.tmp.assert_called()
When side_effect
is a function (or a bound method in this case, which is a kind of function), calling the Mock
will also call the side_effect
with the same arguments.
The Mock()
call will return whatever the side_effect
returns, unless it returns the unnittest.mock.DEFAULT singleton. Then it will return Mock.return_value instead.
回答2:
Or you can decorate the method to test:
def check_called(fun):
def wrapper(self, *args, **kw):
attrname = "_{}_called".format(fun.__name__)
setattr(self, attrname, True)
return fun(self, *args, **kw)
return wrapper
a = A()
a.tmp = check_called(a.tmp)
b(a)
assert(getattr(a, "_tmp_called", False))
but MagicMock's side_effect
is definitly a better solution if you're already using Mock ;)
来源:https://stackoverflow.com/questions/50970170/python-check-if-a-method-is-called-without-mocking-it-away