You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何追踪Python自定义Mock类的方法调用记录?

解决方法

要追踪Mock类方法的调用详情,有几种实用的Python测试技巧,以下是具体实现:

方案1:给自定义Mock类的方法添加Mock包装

保留你原有MockAPIClass的业务逻辑,同时用unittest.mock.Mock包装方法来追踪调用。

修改测试代码:

from unittest import mock
from django.test import TransactionTestCase
from .file import MockAPIClass
from .util import func_to_test_that_calls_client

class TestUils(TransactionTestCase):
    def setUp(self):
        self.api_call_patcher = mock.patch('path.to.mocked.class.instantiation')
        self.patch_api = self.api_call_patcher.start()
        
        # 实例化自定义Mock类
        self.mock_api = MockAPIClass()
        # 用Mock包装get_some_data方法,保留原有返回逻辑
        self.mock_api.get_some_data = mock.Mock(wraps=self.mock_api.get_some_data)
        
        self.patch_api.return_value = self.mock_api

    def tearDown(self):
        mock.patch.stopall()

    def test_util_func(self):
        test_arg = "test"
        res = func_to_test_that_calls_client(test_arg)

        self.assertTrue(res)
        self.patch_api.assert_called_once()
        # 验证get_some_data的调用参数和次数
        self.mock_api.get_some_data.assert_called_once_with(test_arg)
        # 获取调用详情
        call_args = self.mock_api.get_some_data.call_args
        self.assertEqual(call_args[0][0], test_arg)

方案2:直接使用MagicMock替代自定义Mock类

如果不需要自定义Mock的复杂返回逻辑,直接用unittest.mock.MagicMock更简洁,自带完整的调用追踪能力:

修改测试代码:

from unittest import mock
from django.test import TransactionTestCase
from .util import func_to_test_that_calls_client

class TestUils(TransactionTestCase):
    def setUp(self):
        self.api_call_patcher = mock.patch('path.to.mocked.class.instantiation')
        self.patch_api = self.api_call_patcher.start()
        
        # 创建MagicMock实例,设置get_some_data的返回值
        self.mock_api = mock.MagicMock()
        self.mock_api.get_some_data.return_value = "test - 123"  # 模拟原有返回格式
        
        self.patch_api.return_value = self.mock_api

    def tearDown(self):
        mock.patch.stopall()

    def test_util_func(self):
        test_arg = "test"
        res = func_to_test_that_calls_client(test_arg)

        self.assertEqual(res, "test - 123")
        self.patch_api.assert_called_once()
        self.mock_api.get_some_data.assert_called_once_with(test_arg)
        # 查看所有调用记录
        print(self.mock_api.get_some_data.call_args_list)

方案3:在自定义Mock类中手动添加调用追踪

如果必须保留自定义Mock的全部逻辑,可以在类中添加调用记录属性:

修改Mock类代码:

from faker import Factory

faker = Factory.create()

class MockAPIClass:
    def __init__(self):
        # 初始化调用记录列表
        self.get_some_data_calls = []

    def get_some_data(self, data):
        # 记录每次调用的参数
        self.get_some_data_calls.append(data)
        return f"{data} - {faker.pyint()}"

修改测试代码:

from unittest import mock
from django.test import TransactionTestCase
from .file import MockAPIClass
from .util import func_to_test_that_calls_client

class TestUils(TransactionTestCase):
    def setUp(self):
        self.api_call_patcher = mock.patch('path.to.mocked.class.instantiation')
        self.patch_api = self.api_call_patcher.start()
        self.mock_api = MockAPIClass()
        self.patch_api.return_value = self.mock_api

    def tearDown(self):
        mock.patch.stopall()

    def test_util_func(self):
        test_arg = "test"
        res = func_to_test_that_calls_client(test_arg)

        self.assertTrue(res)
        self.patch_api.assert_called_once()
        # 验证调用记录
        self.assertEqual(self.mock_api.get_some_data_calls, [test_arg])
        self.assertEqual(len(self.mock_api.get_some_data_calls), 1)

内容的提问来源于stack exchange,提问作者Wold

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 08:15:40