如果参数包含另一个模拟,则断言模拟参数

Assert mock arguments if arguments include another mock

我有一个函数,例如:

def my_function1(my_obj, my_arg):
    # do something
    return

在我的单元测试中,我想测试第二个函数是否使用指定的参数调用此函数:

def my_function2():
    obj1 = SomeClassObject()
    for arg in ["a", "b", "c"]:
        my_function1(obj1, arg)

为了测试,我模拟了对象,SomeClassObject。而且我还模拟了 my_function1 这样我就可以监视它是如何被调用的。所以我的单元测试看起来像这样:

import unittest
from unittest.mock import patch, call

class MyTest(unittest.TestCase):

    @patch("__main__.SomeClassObject", autospec=True)
    @patch("__main__.my_function1")
    def test_my_function2_calls_my_function1(self, mock_function1, mock_class_object):
        my_function2()
        calls = [call(mock_class_object, "a"),
                 call(mock_class_object, "b"),
                 call(mock_class_object, "c")]
        mock_function1.assert_has_calls(calls)

但是这给出了 3 次以下错误:

AssertionError: (TypeError("missing a required argument: 'my_arg'")

我逐步使用交互式调试器,发现 mock_function1._mock_call_args_list

[call(<MagicMock name='SomeClassObject' id='140060802853296'>, 'a'),
 call(<MagicMock name='SomeClassObject' id='140060802853296'>, 'b'),
 call(<MagicMock name='SomeClassObject' id='140060802853296'>, 'c')]

这与我打印call(mock_class_object, "a")等时得到的完全相同。id完全相同。 所以看起来当我 运行 .assert_has_calls MagicMock 对象搞砸了。

有谁知道我该如何正确地做到这一点?

我不确定您为什么会收到该错误消息,但您测试了 class 而不是对象作为参数。这是应该起作用的:

class MyTest(unittest.TestCase):
    @patch("__main__.SomeClassObject", autospec=True)
    @patch("__main__.my_function1")
    def test_my_function2_calls_my_function1(self, mock_function1, mock_class):
        my_function2()
        mock_class_object = mock_class.return_value
        calls = [call(mock_class_object, "a"),
                 call(mock_class_object, "b"),
                 call(mock_class_object, "c")]
        mock_function1.assert_has_calls(calls)