pytest如何结合fixture模拟作为参数传入的Object类实例测试foo函数
小提示:你给出的示例中
Object类的get_data方法作为实例方法缺少self参数,实际运行会报错,测试前建议先修正为:def get_data(self): return self.data.copy()
pytest 结合fixture与mock的规范实现方案
推荐使用pytest官方维护的pytest-mock插件来处理mock逻辑,无需手动管理mock的生命周期,会自动在每个测试用例结束后清理mock,避免用例之间互相污染。安装方式:pip install pytest-mock
方案1:基于真实Object实例,仅mock get_data方法
该方案保留Object实例其他原有属性、方法的逻辑,仅替换get_data的返回值,更贴近真实运行场景,适合大部分测试场景。
import pytest # 替换为你实际的模块导入路径 from your_module import Object, foo @pytest.fixture def mock_object(mocker): # 初始化真实的Object实例,可传入任意初始data raw_data = {"default": "raw_value"} obj = Object(raw_data) # 预设get_data方法的返回值,可根据测试需求修改 test_return_data = {"test_key": "test_value", "test_list": [1,2,3]} # 仅mock该实例的get_data方法 mocker.patch.object(obj, "get_data", return_value=test_return_data) return obj
测试用例使用方式:
def test_foo(mock_object): # 直接传入fixture生成的实例即可 foo_result = foo(mock_object) # 可选:验证get_data被正确调用 mock_object.get_data.assert_called_once() # 补充你自己的断言逻辑验证foo的输出符合预期 # assert foo_result == xxx
方案2:完全模拟Object实例,不依赖原有类实现
如果测试foo时完全不需要用到Object类的其他逻辑,只需要一个符合类型要求的替身,可以直接构造Mock实例,无需导入原有Object类:
import pytest from unittest.mock import Mock # 替换为你实际的模块导入路径 from your_module import foo @pytest.fixture def mock_object(): # 构造Mock实例模拟Object的行为 mock_obj = Mock(name="ObjectMock") # 预设get_data的返回值 mock_obj.get_data.return_value = {"test_key": "test_value", "test_list": [1,2,3]} return mock_obj
测试用例的使用方式和方案1完全一致。
进阶:支持动态自定义返回值的工厂fixture
如果不同测试用例需要get_data返回不同的测试数据,可以使用工厂模式的fixture:
@pytest.fixture def mock_object_factory(mocker): def _mock_object(return_data): obj = Object({"raw": "data"}) mocker.patch.object(obj, "get_data", return_value=return_data) return obj return _mock_object
使用方式:
def test_foo_different_scenarios(mock_object_factory): # 场景1:返回空数据 empty_obj = mock_object_factory({}) result1 = foo(empty_obj) # 对应场景的断言逻辑 # 场景2:返回包含特殊字符的数据 special_obj = mock_object_factory({"key": "<script>alert(1)</script>"}) result2 = foo(special_obj) # 对应场景的断言逻辑
内容的提问来源于stack exchange,提问作者erwere32
相关产品推荐
相关产品推荐

