2

库模块:

# mod.py
def foo():
    bar1("arg1")
    bar2("arg2x", "arg2y")

def bar1(x):
    pass

def bar2(x, y):
    pass

测试模块:

# test_mod.py
from mod import foo

def test_foo(mocker):
    mock = mocker.MagicMock()
    mock.attach_mock(mocker.patch("mod.bar1"), "b1")
    mock.attach_mock(mocker.patch("mod.bar2", autospec=True), "b2")
    foo()
    mock.assert_has_calls(
        [
            mocker.call.b1("arg1"),
            mocker.call.b2("arg2x", "arg2y"),
        ]
    )

mocker夹具来自插件pytest-mock。使用执行MCVEpython -m pytest

由于奇怪的 原因,该测试失败了。

E       AssertionError: Calls not found.
E       Expected: [call.b1('arg1'), call.b2('arg2x', 'arg2y')]
E       Actual: [call.b1('arg1')]

没有autospec它可以工作。使用 autospec 会破坏该attach_mock功能吗?应该如何在不丢失它们的 autospec 的情况下对依赖调用的 order和argsfoo进行assert测试?bar1bar2

4

1 回答 1

1

这实际上是 Python 中的一个错误。它在 2019 年末得到修复,补丁版本:

原始帖子中的测试现在正在通过一个固定版本。Python 3.6 没有向后移植,它只是现在的安全性,因此将永远存在错误。

这些是相关的 PR 和问题跟踪链接:

bpo-21478 Autospec 函数应将模拟调用传播到父级

bpo-21478当 autospecced 对象用作子对象时,记录对父对象的调用attach_mock

bpo-38473处理使用的自动指定函数和方法attach_mock

Karthikeyan Singaravelan 的补丁。

于 2020-05-06T05:40:57.630 回答