如何Mock类的property属性使其返回另一个属性值?
如何Mock Python类的@property属性使其返回实例的其他属性值
原类代码
class Something(): def __init__(self, name) -> None: self.name = name @property def value(self): # 实际场景中是复杂逻辑 return "no"
需求
MockSomething类的.value属性,让它返回对应实例的.name属性值。
尝试过的错误方式
方式一:直接用patch.object指定side_effect和autospec=True
def side_effect(side_self: Something): return side_self.name with patch.object(Something, "value", side_effect=side_effect, autospec=True): # 测试代码 ...
错误现象:实例的.value返回MagicMock对象,而非预期的name字符串。
方式二:结合PropertyMock和side_effect
def side_effect(side_self: Something): return side_self.name with patch.object(Something, "value", new_callable=PropertyMock, side_effect=side_effect): # 测试代码 ...
错误现象:报错.side_effect() missing 1 required positional argument: 'side_self',因为PropertyMock的side_effect函数不会自动传入实例对象。
正确解决方案
核心思路是自定义一个继承自PropertyMock的类,重写它的__get__方法——这个方法在属性被获取时会自动接收实例对象,我们可以在这里返回实例的.name属性:
from unittest.mock import patch, PropertyMock class CustomPropertyMock(PropertyMock): def __get__(self, instance, owner): # 当通过类访问属性时(而非实例),返回自身 if instance is None: return self # 返回实例的name属性 return instance.name # 测试代码示例 with patch.object(Something, "value", new_callable=CustomPropertyMock): obj_a = Something("Alice") print(obj_a.value) # 输出: Alice obj_b = Something("Bob") print(obj_b.value) # 输出: Bob
这种方式能确保每个实例的.value属性都动态返回自身的.name值,完全符合需求。
内容的提问来源于stack exchange,提问作者Guillaume
相关产品推荐
相关产品推荐

