Tim*_*ard 9 python unit-testing mocking
我在 patch.object 中遇到了 side_effect 参数的一个令人惊讶的行为,其中替换原始函数的函数没有收到 self
class Animal():
def __init__(self):
self.noise = 'Woof'
def make_noise(self):
return self.noise
def loud(self):
return self.noise.upper() + '!!'
from unittest.mock import patch
dog = Animal()
dog.make_noise()
with patch.object(Animal, 'make_noise', side_effect=loud):
dog.make_noise()
Run Code Online (Sandbox Code Playgroud)
这给:
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "/lustre/home/production/Applications/python/python-3.4.4/lib/python3.4/unittest/mock.py", line 902, in __call__
return _mock_self._mock_call(*args, **kwargs)
File "/lustre/home/production/Applications/python/python-3.4.4/lib/python3.4/unittest/mock.py", line 968, in _mock_call
ret_val = effect(*args, **kwargs)
TypeError: loud() missing 1 required positional argument: 'self'
Run Code Online (Sandbox Code Playgroud)
如果我将loud功能更改为
def loud(*args, **kwargs):
print(args)
print(kwargs)
Run Code Online (Sandbox Code Playgroud)
我得到以下输出:
()
{}
Run Code Online (Sandbox Code Playgroud)
有没有办法从对象中替换函数并仍然接收自我?
Mar*_*ers 10
self仅提供给绑定方法(因为函数是描述符)。甲Mock对象是没有这样的方法,该side_effect功能未绑定,所以self确实不会在要传递。
如果您必须访问side_effect对象中的实例,则必须使用实际函数修补类上的函数:
with patch.object(Animal, 'make_noise', new=loud):
Run Code Online (Sandbox Code Playgroud)
现在make_noise被类loud上的函数替换Animal,所以它将被绑定:
>>> with patch.object(Animal, 'make_noise', new=loud):
... dog.make_noise()
...
'WOOF!!'
Run Code Online (Sandbox Code Playgroud)
另一种方法是设置autospec=True,此时mock将使用一个真正的函数来模拟make_noise():
>>> with patch.object(Animal, 'make_noise', autospec=True, side_effect=loud):
... dog.make_noise()
...
'WOOF!!'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3604 次 |
| 最近记录: |