2

How can I test in pytest-mock whether a method has been called with a corresponding object or not?

My object is the following:

class Obj:

    def __init__(self):
        self.__param = []
        self.__test = []

    @property
    def param(self):
        return self.__param

    @param.setter
    def param(self, value):
        self.__param = value
    
    # both methods: getter and setter are also available for the self.__test     


    # This is just a dummy test object
class Test:
      
    def call_method(self, text:str):
        obj = Obj()
        obj.param = [("test", "1"), ("test2", "2")]
        self.test_call(text, obj)

    def test_call(self, text:str, object: Obj):
        pass

My test is the following:

def test_method(mocker):
    mock_call = mocker.patch.object(Test, "test_call")

    test = Test()
    test.call_method("text")

    expected_obj = Obj()
    expected_obj.param = [("test", "1"), ("test2", "2")]

    mock_call.assert_called_once_with("text", expected_obj)

At the moment I get the error message:

assert ('text...7fbe9b2ae4e0>) == ('text...7fbe9b2b5470>)

It seems that pytest checks if both objects have identical adresses. I just want to check if both objects have the same parameters. How can I check this?

MrBean Bremen
  • 14,916
  • 3
  • 26
  • 46
user5580578
  • 1,134
  • 1
  • 12
  • 28

1 Answers1

2

You cannot use assert_called_with if you don't want to check object identitiy - instead you have to check the arguments directly:

def test_method(mocker):
    mock_call = mocker.patch.object(Test, "test_call")

    test = Test()
    test.call_method("text")

    mock_call.assert_called_once()
    assert len(mock_call.call_args[0]) == 2
    assert mock_call.call_args[0][0] == "text"
    assert mock_call.call_args[0][1].param == [("test", "1"), ("test2", "2")]

E.g. you have to check separately that it was called once, and that the arguments have the correct properties.

Note that call_args is a list of tuples, where the first element contains all positional arguments, and the second element all keyword arguments, therefore you have to use [0][0] and [0][1] indexes to address the two positional arguments.

From Python 3.8 on, you can also access the positional arguments in call_args via args and the keyword arguments via kwargs.

MrBean Bremen
  • 14,916
  • 3
  • 26
  • 46