如何追踪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
相关产品推荐
相关产品推荐

