Python使用Mock修改Enum枚举值报AttributeError问题求助
报错原因
Python 标准库Enum枚举类的成员在类定义完成后是单例只读对象,成员的name、value属性都没有实现赋值逻辑,属于不可修改的属性;同时你的FileName还继承了str,属于字符串枚举,值本身也是不可变类型,直接执行FileName.HANDLES_CSV.value = xxx尝试修改只读属性,就会抛出AttributeError: can't set attribute错误。
这个报错和Mock本身没有关系,就算不用Mock直接写FileName.HANDLES_CSV.value = "test.json"也会触发完全一样的错误。
正确Mock修改枚举值的方案
单元测试场景下优先用mock.patch.object做临时替换,不要尝试直接修改枚举成员的value属性,通过上下文管理器可以做到测试结束后自动恢复原枚举值,不会污染其他测试用例。
- 方案1:直接替换枚举成员为测试值(适合str枚举场景)
如果你的枚举继承了str,直接把对应成员替换为目标字符串即可,上下文内访问成员、访问.value都会拿到你设置的测试值:
from enum import Enum from unittest import mock class FileName(str, Enum): HANDLES_CSV = "handles.csv" HANDLES_JSON = "handles.json" def test_function(): with mock.patch.object(FileName, "HANDLES_CSV", "test.json"): print(FileName.HANDLES_CSV) # 输出 test.json print(FileName.HANDLES_CSV.value) # 输出 test.json
- 方案2:替换枚举成员为Mock对象(适合需要自定义value属性的场景)
如果你需要灵活控制成员的属性、返回值,可以直接把整个枚举成员替换为Mock实例,之后可以随意修改Mock的属性,不会触发Enum的只读限制:
from enum import Enum from unittest import mock class FileName(str, Enum): HANDLES_CSV = "handles.csv" HANDLES_JSON = "handles.json" def test_function(): mock_enum_member = mock.Mock() mock_enum_member.value = "test.json" with mock.patch.object(FileName, "HANDLES_CSV", mock_enum_member): print(FileName.HANDLES_CSV.value) # 输出 test.json # 也可以给Mock设置其他返回值、副作用,满足复杂测试需求
注意:不要通过修改Enum内部私有属性(比如
_value_、_value2member_map_)的方式改枚举值,不同Python版本的Enum内部实现差异大,这类写法兼容性很差,很容易引出莫名其妙的问题。
内容的提问来源于stack exchange,提问作者Yousra07
相关产品推荐
相关产品推荐

