【问题标题】:Assert mock arguments if arguments include another mock如果参数包含另一个模拟,则断言模拟参数
【发布时间】:2020-08-08 07:52:15
【问题描述】:

我有一个函数,例如:

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)

但这会给出以下错误三遍:

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 对象会搞砸。

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

【问题讨论】:

  • 当我运行您在 Python 3.6.9 中提供的代码时,我无法重现您的错误。你运行的是什么版本的 Python?你是如何运行你的测试的(即你是使用python -m unittest,还是最后有一个if __name__ == '__main__': unittest.main()子句)?请发布导致您的问题的确切代码。
  • 我试图在我的示例代码中重现该错误,但也无法重现。经过大量挖掘,我最终意识到我的问题只是由于一个错字。

标签: python unit-testing mocking monkeypatching


【解决方案1】:

我不确定您究竟为什么会收到该错误消息,但您测试的是类而不是对象作为参数。这应该是可行的:

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)

【讨论】:

  • 是的,我在编写示例代码时也注意到了这一点。原来我的问题是由于一个错字造成的——我在call 函数中使用了方括号来列出参数,所以它当然找不到第二个参数。虽然有一些答案。
  • 啊,好吧,我想知道那个错误消息 - 所以问题中显示的代码已经解决了这个问题。感谢您的积分:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-01
  • 2014-05-05
  • 2022-07-03
  • 2023-03-08
  • 2012-09-22
  • 2019-02-10
  • 2022-10-05
相关资源
最近更新 更多