如何检查是否使用预期对象调用了方法

How to check if method is called with the expected objects

如何在 pytest-mock 中测试某个方法是否被相应的对象调用?

我的对象如下:

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

我的测试如下:

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)

此时我收到错误信息:

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

pytest 似乎检查两个对象是否具有相同的地址。我只想检查两个对象是否具有相同的参数。我该如何检查?

如果您不想检查对象身份,则不能使用 assert_called_with - 您必须直接检查参数:

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")]

例如您必须单独检查它是否被调用过一次,以及参数是否具有正确的属性。

注意 call_args 是一个 list of tuples,其中第一个元素包含所有位置参数,第二个元素包含所有关键字参数,因此您必须使用 [0][0][0][1] 索引来处理两个位置参数。