[英]python patch with side_effect on Object's method is not called with self
我在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()
这给:
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'
如果我将loud
功能更改为
def loud(*args, **kwargs):
print(args)
print(kwargs)
我得到以下输出:
()
{}
有没有办法从一个对象替换一个函数,仍然接收自己?
self
仅为绑定方法提供 (因为函数是描述符 )。 Mock
对象不是这样的方法,并且side_effect
函数没有绑定,因此self
确实不会被传入。
如果必须访问side_effect
对象中的实例,则必须使用实际函数在类上修补该函数:
with patch.object(Animal, 'make_noise', new=loud):
现在make_noise
被Animal
类上的loud
函数取代,所以它将被绑定:
>>> with patch.object(Animal, 'make_noise', new=loud):
... dog.make_noise()
...
'WOOF!!'
另一种方法是设置autospec=True
,此时mock
将使用实际函数来模拟make_noise()
:
>>> with patch.object(Animal, 'make_noise', autospec=True, side_effect=loud):
... dog.make_noise()
...
'WOOF!!'
另请参阅模拟入门 部分中的Mocking Unbound Methods部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.