python - 为什么模拟在调用时忽略传递给模拟方法的实例/对象?

标签 python unit-testing mocking

我最近注意到,如果我使用 mock.patch 模拟一个方法,它不会在 call_args 字段中列出传递给模拟方法的实例对象。这是设计使然吗?下面的代码/输出可能更好地解释我的意思:

#!/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: ((), {})

可以看到实例对象在替换bark时被传递给了new_method。但是您无法在模拟方法的 call_args 中看到它。这不奇怪吗?我正在使用 1.01 版的 python 模拟库。

最佳答案

通过

with patch.object(Dog, "bark"):

您正在修补 Dog.bark 方法的静态实例,因为您正在修补 Dog 类而不是 Dog 对象。

现在 mock 方法将作为静态方法而不是对象方法调用:这意味着 self 属性不会被传递。

如果你想创建一个与原始方法具有相同签名的补丁,你可以使用 autospec=True 属性:在这种情况下,模拟方法将是一个对象方法而不是静态方法。

>>> 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>)

关于python - 为什么模拟在调用时忽略传递给模拟方法的实例/对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32419283/

相关文章:

javascript - 单元测试 Sails JS 1.0 助手

java - Powermock junit5 和mockito2.x 不工作 RunnerTestSuiteChunker 未找到

python - 脚本正在跳过功能

python - 使用 beautifulsoup 解析 HTML 给出 "None"

python - 如何将枚举与 SQLAlchemy 和 Alembic 一起使用?

python - 每行numpy的快速列洗牌

javascript - getByText 用于通过动态生成的字符串将文本拆分为单独的行

vb.net - vb.net 项目的单元测试

c# - 如何模拟引用私有(private)对象实例的 .NET 代码?

java - 模拟引用对象