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

如何mock类中带self参数的@property属性方法?

针对特定实例mock属性的两种解决方案

1. Mock @property 装饰的属性

@property本质是描述符,它的getter逻辑存放在fget属性中,直接patch这个fget方法即可拿到self参数,实现按实例条件返回自定义值:
首先定义补丁逻辑:

from unittest.mock import patch
from functools import partial

# 保留原property的getter逻辑,避免其他实例受影响
orig_conf_getter = Thing.configuration_filename.fget

def patched_conf_getter(custom_path, self):
    # 按实例属性判断是否要返回自定义路径
    if self.name == 'test_thing':
        return custom_path
    # 其他实例走原逻辑
    return orig_conf_getter(self)

测试类的装饰器写法和你原有逻辑完全兼容,仅需要修改patch的目标:

@patch.object(Thing.configuration_filename, 'fget', side_effect=partial(patched_conf_getter, 'testdata/test_1.yaml'))
class ConfigurationTests(TestCase):
    def test_sample(self, mocked_getter):
        # 匹配条件的实例返回自定义路径
        test_inst = Thing('test_thing')
        assert test_inst.configuration_filename == 'testdata/test_1.yaml'
        # 普通实例不受影响
        normal_inst = Thing('normal')
        assert normal_inst.configuration_filename == '/configuration/normal_configuration.yaml'

2. Mock init 中初始化的实例属性

这种实例级别的属性有两种处理方式:

  • 如果测试中可以直接拿到实例对象,直接赋值覆盖即可,最简单高效:
test_inst = Thing('test_thing')
test_inst.configuration_name = 'testdata/test_1.yaml'
  • 如果无法直接干预实例创建过程,可以patch __init__方法,在初始化完成后按条件赋值:
# 保留原初始化逻辑
orig_init = Thing.__init__

def patched_init(custom_path, self, name, *args, **kwargs):
    # 先执行原初始化逻辑
    orig_init(self, name, *args, **kwargs)
    # 匹配条件的实例覆盖属性
    if self.name == 'test_thing':
        self.configuration_name = custom_path

# 测试类装饰器写法
@patch.object(Thing, '__init__', side_effect=partial(patched_init, 'testdata/test_1.yaml'), autospec=True)
class ConfigurationTests(TestCase):
    def test_sample(self, mocked_init):
        test_inst = Thing('test_thing')
        assert test_inst.configuration_name == 'testdata/test_1.yaml'

以上两种方案都不需要修改原有业务代码,不需要将@property改为普通方法,完全满足仅针对特定实例mock的需求。

内容的提问来源于stack exchange,提问作者fatz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 11:30:06