Python单元测试:MagicMock返回对象而非预期值的问题
问题:Mock类属性时返回MagicMock而非预期值
原代码
待测试的类定义如下:
class SomeClass: _attribute = None def __init__(self, attribute): self._attribute = attribute @property def attribute(self): print("abc") return self._attribute class SomeChildClass: context: SomeClass def __init__(self): pass def print_attribute(self): print(self.context.attribute)
测试需求
要测试SomeChildClass.print_attribute方法,希望完全MockSomeClass及其attribute属性,避免创建真实的SomeClass实例。
失败的尝试
尝试1:MagicMock实例 + PropertyMock patch类属性
def test_print_attribute(self): with patch('app.some_class.SomeClass.attribute', new_callable=PropertyMock) as mock_attr: mock_attr.return_value = "TEST" some_class = MagicMock() self.child_class = SomeChildClass() self.child_class.context = some_class self.child_class.print_attribute()
输出结果:
<MagicMock name='mock.attribute' id='2576201109456'>
尝试2:直接patch整个SomeClass类
@patch('app.some_class.SomeClass') def test_print_attribute(self, mock_some_class): child_class = SomeChildClass() child_class.context = mock_some_class mock_some_class.attribute.return_value = "TEST" child_class.print_attribute()
输出结果:
<MagicMock name='SomeClass.attribute' id='1701032644768'>
解决方法
问题核心:@property是类级别的描述符,直接给MagicMock实例或类Mock设置普通return_value不会触发PropertyMock的行为,必须给Mock实例的类绑定PropertyMock。
方法1:给MagicMock实例绑定PropertyMock
def test_print_attribute(self): # 创建PropertyMock并指定返回值 mock_attr = PropertyMock(return_value="TEST") # 创建MagicMock实例 some_class = MagicMock() # 关键:给MagicMock实例的类型设置attribute属性为PropertyMock type(some_class).attribute = mock_attr self.child_class = SomeChildClass() self.child_class.context = some_class self.child_class.print_attribute() # 输出:TEST
方法2:patch整个类后给实例设置PropertyMock
@patch('app.some_class.SomeClass') def test_print_attribute(self, mock_some_class): # 获取类Mock的实例对象(调用类时返回的Mock) mock_instance = mock_some_class.return_value # 给实例的类型设置PropertyMock type(mock_instance).attribute = PropertyMock(return_value="TEST") child_class = SomeChildClass() child_class.context = mock_instance child_class.print_attribute() # 输出:TEST
内容的提问来源于stack exchange,提问作者michaelgr22
相关产品推荐
相关产品推荐

