首页 > 解决方案 > 使用自动指定的模拟跟踪呼叫顺序

问题描述

unittest.mock在 Python 3.6 中的模块遇到了一些奇怪的问题。

在我的测试中,我将模拟附加到父模拟,以便能够跟踪它们被调用的顺序。

这是一个玩具示例来说明这个问题:

import unittest
from unittest import mock


def add(a, b):
    return a + b


def div(a, b):
    return a / b


def add_plus_div(a, b):
    return [add(a, b), div(a, b)]


@mock.patch("__main__.add")
@mock.patch("__main__.div")
class MyTests(unittest.TestCase):

    def test_one(self, mock_div, mock_add):

        parent = mock.Mock()
        parent.attach_mock(mock_div, "div")
        parent.attach_mock(mock_add, "add")

        add_plus_div(1, 2)

        parent.assert_has_calls([
            mock.call.add(1, 2),
            mock.call.div(1, 2),
        ])


if __name__ == '__main__':
    unittest.main()

这工作正常,并且如您所料通过。

但是,如果您自动指定模拟:

@mock.patch("__main__.add", autospec=True)
@mock.patch("__main__.div", autospec=True)
class MyTests(unittest.TestCase):

    def test_one(self, mock_div, mock_add):

        parent = mock.Mock()
        parent.attach_mock(mock_div, "div")
        parent.attach_mock(mock_add, "add")

        add_plus_div(1, 2)

        parent.assert_has_calls([
            mock.call.add(1, 2),
            mock.call.div(1, 2),
        ])

你会失败:

AssertionError: Calls not found.
Expected: [call.add(1, 2), call.div(1, 2)]
Actual: []

有谁知道为什么自动指定会破坏事情,以及我如何跟踪许多自动指定的模拟函数的调用顺序?

标签: pythonmockingpython-unittest

解决方案


看起来这是一个已知但长期存在的错误的实例:https ://bugs.python.org/issue21478


推荐阅读