mock类方法时应确保patch位置与实际调用路径一致,优先使用patch.object(instance, 'method');注意私有方法需用改写名\_ClassName\_\_name;启用autospec=True可防止拼写错误但限制动态属性。

mock类方法时,别 patch 错了位置
最常见错误是直接 patch('module.Class.method'),结果测试里调用的却是实例方法——patch 的目标必须和实际调用路径一致。比如 obj.do_something() 走的是实例绑定方法,应 patch 实例或用 patch.object(obj, 'do_something');若代码里写的是 MyClass.do_something()(显式类调用),才考虑 patch('module.MyClass.do_something')。
另一个关键点:被 patch 的方法在测试执行前必须尚未被访问过。如果类定义里已有 self._helper = self._some_private_logic 这类赋值,patch 就可能失效——因为属性已在实例初始化时绑定完毕。
- 优先用
patch.object(instance, 'method_name'),精准、不污染全局 - 若需 patch 类级别方法(如
@staticmethod),目标应为MyClass.static_method,而非实例 - 避免在
setUp中提前调用被 mock 的方法,否则 mock 可能被绕过
mock属性要分清 return_value 和属性赋值
Mock 对象的 return_value 只影响「调用」行为(即加括号),而属性访问(不加括号)走的是另一套机制。例如 mock_obj.data 是属性读取,mock_obj.data() 才是方法调用。
常见误配:mock_obj.data.return_value = 'ok' 对 mock_obj.data 读取无效;正确做法是直接赋值:mock_obj.data = 'ok'。链式调用如 a.b.c 则需逐层配置:mock_obj.b.c = 'final' 或用 configure_mock:
立即学习“Python免费学习笔记(深入)”;
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
mock_obj.configure_mock(**{'b.c': 'final'})
-
mock.attr = value→ 模拟属性读取 -
mock.method.return_value = x→ 模拟方法调用返回值 - 链式结构推荐用
configure_mock,比嵌套点号更清晰、不易漏层级
双下划线私有方法的 patch 必须用名称改写后的真实名
Python 对 __name 形式的私有方法会自动改写为 _ClassName__name。如果你写 patch('module.MyClass.__process'),patch 根本找不到目标——它只在运行时存在改写后的名字。
安全做法永远是:对实例用 patch.object(obj, '_MyClass__process'),而不是 patch 类本身。这样既避开命名空间查找陷阱,又不会影响其他实例。
- 不要 patch 类定义里的
__xxx,而要 patch 实例上的改写名 - 单下划线私有方法(
_name)无名称改写,可直接 patch - 若该方法是
@classmethod,patch 目标得是MyClass._MyClass__name,不是实例
autospec=True 不是万能,但不用容易漏断言
没加 autospec=True 的 mock,允许你访问任何不存在的属性或方法,比如 mock.nonexistent.attr.call() 都不会报错——这会让测试看起来通过,实则掩盖了拼写错误或 API 变更。
启用 autospec=True 后,mock 会严格按原对象的签名和属性结构生成,访问不存在的属性直接抛 AttributeError,调用参数不匹配也会立刻失败。但它也有代价:无法 mock 动态添加的属性(如某些 ORM 实例),且对带 __getattr__ 的类支持有限。
- 对明确知道结构的类(如你自己写的 service 类),默认加
autospec=True - 对动态属性多的对象(如
requests.Response),可用spec_set=True折中:限制属性写入,但允许读取 - pytest-mock 的
mocker.patch默认不启用 autospec,必须显式传参

















