我最近注意到,如果我使用mock.patch模拟一个方法,它不会列出传递给call_args字段中的mocked方法的实例对象.这是设计的吗?下面的代码/输出可能更好地解释我的意思:
#!/usr/bin/env python2
from mock import patch
class Dog(object):
def bark(self):
print("Woof woof!")
Dog().bark()
def new_method(*args):
print("args = %s" % str(args))
Dog.bark = new_method
Dog().bark()
with patch.object(Dog, "bark"):
d = Dog()
d.bark()
print("d.bark was called: %s" % str(d.bark.called))
print("d.bark was called with args/kwargs: %s" % str(d.bark.call_args))
输出是:
Woof woof!
args = (<__main__.Dog object at 0x7f42c2dbc3d0>,)
# Mocking bit
d.bark was called: True
d.bark was called with args/kwargs: ((), {})
您可以看到实例对象在替换树皮时传递给new_method.但你无法在模拟方法的call_args中看到它.这不奇怪吗?我正在使用python模拟库的1.01版本.
最佳答案 通过
with patch.object(Dog, "bark"):
您正在修补Dog.bark方法的静态实例,因为您正在修补Dog类而不是Dog对象.
现在,mock方法将被调用为静态方法而不是对象方法:这意味着不会传递self属性.
如果要创建具有与原始方法相同签名的修补程序,可以使用autospec = True属性:在这种情况下,mock方法将是对象方法而不是静态方法.
>>> from mock import patch
>>> with patch.object(Dog, "bark", autospec=True):
... d = Dog()
... d.bark()
... print("d.bark was called with args/kwargs: %s" % str(d.bark.call_args))
...
<MagicMock name='bark()' id='139848306278672'>
d.bark was called with args/kwargs: call(<Dog object at 0x7f30f89ef390>)