You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 13:10:50