简体   繁体   English

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

[英]Assert mock arguments if arguments include another mock

I have a function, for example:我有一个 function,例如:

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

In my unittest, I want to test that a second function calls this function with the specified arguments:在我的单元测试中,我想测试第二个 function 使用指定的 arguments 调用这个 function:

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

For the test, I have mocked the object, SomeClassObject .为了进行测试,我模拟了 object, SomeClassObject And I also mock my_function1 so I can monitor how it is called.我还模拟了my_function1 ,这样我就可以监视它是如何被调用的。 So my unittest looks like this:所以我的单元测试看起来像这样:

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)

But this gives the following error three times:但这三次出现以下错误:

AssertionError: (TypeError("missing a required argument: 'my_arg'")断言错误:(TypeError(“缺少必需的参数:'my_arg'”)

I stepped through using the interactive debugger and I found that the mock_function1._mock_call_args_list is我逐步使用交互式调试器,发现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')]

This is identical to what I get when I print call(mock_class_object, "a") etc. The id is exactly the same.这与我打印call(mock_class_object, "a")等时得到的相同。id 完全相同。 So it looks like when I run .assert_has_calls the MagicMock object messes things up.所以看起来当我运行.assert_has_calls时, MagicMock object 把事情搞砸了。

Does anyone know how I can do this correctly?有谁知道我如何正确地做到这一点?

I'm not sure why exactly you get that error message, but you test for the class instead of the object as the argument.我不确定您为什么会收到该错误消息,但您测试了 class 而不是 object 作为参数。 This is what should work:这是应该起作用的:

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM