简体   繁体   中英

Assert mock arguments if arguments include another mock

I have a function, for example:

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:

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

For the test, I have mocked the object, SomeClassObject . And I also mock my_function1 so I can monitor how it is called. 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'")

I stepped through using the interactive debugger and I found that the mock_function1._mock_call_args_list is

[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. So it looks like when I run .assert_has_calls the MagicMock object messes things up.

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. 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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