是否可仅通过路径字符串使用mock.patch修补类实例属性
问题解答
可以仅通过传入路径字符串的方式完成打补丁,无需提前导入目标类,也不需要使用mock.patch.object,但需要注意属性类型差异和路径规则,否则补丁不会生效。
常见误区说明
你给出的示例代码存在几个容易导致补丁失效的问题:
- 你定义的
a是写在__init__方法里的实例属性,只有类实例化之后才会绑定到实例对象上,类本身不存在a这个属性,直接patch类层面的A.a不会对实例属性生效 - 你写的补丁路径
"config.A.a"不符合Python导入规则,路径需要和目标对象的实际模块路径匹配 - 给属性打补丁时不需要传
return_value参数,这个参数是给函数/方法这类可调用对象指定返回值用的,直接把要替换的属性值作为参数传入即可 - 测试函数内直接使用
A却没有对应导入,会触发NameError,这是Python作用域的基础规则,和mock逻辑无关
正确写法示例
场景1:补丁目标是类属性
如果你的a是定义在类下的类属性,直接传字符串路径给mock.patch即可生效,不需要提前导入类:
首先是待测试的file.py代码:
# file.py class A: a = 1 # 这是类属性,所有实例共享
测试文件test_file.py写法:
import mock # 路径格式为「目标类所在模块.类名.属性名」,第二个参数直接传要替换的值 @mock.patch("file.A.a", 2) def test_a(): # 需要使用时再导入A即可,不需要在文件头部提前导入 from file import A print(A.a) # 输出结果为2,补丁生效
场景2:补丁目标是实例属性
如果a是你示例中定义在__init__里的实例属性,需要调整补丁路径为类实例化后的返回值属性:
待测试的file.py和你给出的示例一致:
# file.py class A: def __init__(self): self.a = 1 # 这是实例属性,每个实例独立持有
测试文件test_file.py写法:
import mock # 路径指定为类实例化返回值的a属性 @mock.patch("file.A.return_value.a", 2) def test_a(): from file import A obj = A() print(obj.a) # 输出结果为2,全程未使用patch.object,也不需要提前导入A
注意事项
- 补丁路径必须是Python解释器可以正常导入的有效路径,如果目标类在嵌套包内,需要写全模块路径,比如类在
src/utils/file.py下,路径就要写为src.utils.file.A.a - mock的路径规则遵循「在哪里使用,就在哪里patch」的原则,如果你的测试文件是通过
from x import y的方式导入目标对象,补丁路径需要对应测试文件所在模块的引用路径
内容的提问来源于stack exchange,提问作者gustavz
相关产品推荐
相关产品推荐

