pytest mock与monkeypatch的区别与使用场景
请对比pytest中mock(unittest.mock / pytest-mock)和monkeypatch的区别,并说明各自适用场景。
回答
小字辈
unittest.mock / pytest-mock:
pytest-mock插件提供mockerfixture,包装了unittest.mockmocker.patch('module.ClassName.method')替换对象- 支持
MagicMock、PropertyMock、patch.object、patch.multiple - 提供断言:
assert_called_once_with()、assert_any_call() - 自动记录调用次数、参数、返回值
- 适合:替换类/函数/属性、模拟返回值、验证调用、模拟外部API
monkeypatch(pytest内置):
monkeypatch.setattr(obj, name, value)— 设置属性monkeypatch.delattr(obj, name)— 删除属性monkeypatch.setenv()/monkeypatch.delenv()— 环境变量monkeypatch.setitem()/monkeypatch.delitem()— 字典修改- 自动恢复初始状态(测试后无需手动清理)
- 适合:修改环境变量、配置、字典,简单替换函数/属性
选型建议:
- 需要断言调用行为 →
mocker(更多功能) - 临时修改环境/配置 →
monkeypatch(更轻量) - 替换纯函数 → 两者皆可
- 复杂mock链 →
mocker