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

Python单例改造后如何Mock模块函数,避免类初始化执行

解决单例模式下Mock类避免触发__init__的方案

方案1:保留原有patch逻辑(推荐,零测试代码改动)

你之前的测试都是patch原始类path.to.some.module.MyClass,这个逻辑完全可以复用。核心思路是在单例初始化前完成patch,让单例拿到的是Mock类而非真实类,从根源上避免__init__执行。

如果用pytest,直接在conftest.py里加一个全局自动生效的fixture:

import pytest
from unittest.mock import patch

@pytest.fixture(autouse=True, scope="session")
def mock_my_class():
    # 提前patch原始类,覆盖所有测试会话
    with patch('path.to.some.module.MyClass') as mock_cls:
        yield mock_cls

这样数百个原有测试无需任何修改,单例初始化时会自动使用Mock类,不会触发真实的初始化逻辑。

方案2:Mock单例的对外入口

如果不想全局patch,可以直接Mock暴露单例的入口函数(比如get_my_class),跳过单例内部的实例创建逻辑:

from unittest.mock import patch, Mock

@patch('path.to.some.module.get_my_class')
def test_example(mock_get):
    # 自定义Mock实例的行为
    mock_instance = Mock()
    mock_instance.some_method.return_value = "test_output"
    mock_get.return_value = mock_instance
    
    # 执行测试逻辑
    # ...

这种方式完全隔离真实类的初始化,不需要关心单例内部的_my_class属性。

为什么直接patchMyClassSingleton._my_class会触发__init__

因为单例的初始化逻辑(比如get_instance方法)会在属性为空时自动创建MyClass实例。当你patch_my_class时,若单例还未初始化,patch操作可能触发属性检查,间接调用了真实类的__init__;如果单例已在导入时初始化,patch只能替换现有实例,无法阻止之前的初始化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 23:20:07