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

如何Mock导入阶段执行的函数?含ABC类多方法Mock场景

如何Mock导入阶段自动执行的类初始化与方法调用

当导入xyz.py时,代码会自动实例化ABC类并调用obj.print_1(),导致输出"making object"和"printed 1"。要Mock__init__()、print_1()和print_2()这三个方法,核心是在导入xyz.py之前完成Mock配置,避免原代码的副作用。

以下是基于Python标准库unittest.mock的具体实现方案:

步骤1:提前Mock ABC类

由于xyz.py在导入阶段就会执行实例化和方法调用,必须先替换abc模块中的ABC类为Mock对象,再导入xyz。

示例测试代码

from unittest.mock import patch, MagicMock

# 用patch上下文管理器替换abc.ABC类
with patch('abc.ABC') as mock_abc_cls:
    # 获取Mock类的实例对象(对应xyz里的obj)
    mock_obj = mock_abc_cls.return_value
    
    # 分别Mock三个方法,屏蔽原方法的print输出
    mock_obj.__init__ = MagicMock(return_value=None)
    mock_obj.print_1 = MagicMock(return_value=None)
    mock_obj.print_2 = MagicMock(return_value=None)
    
    # 此时导入xyz,执行的是Mock后的逻辑
    import xyz
    
    # 验证调用行为(可选)
    mock_abc_cls.assert_called_once()  # 确认ABC()被实例化一次
    mock_obj.print_1.assert_called_once()  # 确认print_1()被调用一次
    
    # 测试func(),验证print_2的调用参数
    xyz.func()
    mock_obj.print_2.assert_called_once_with(2)

关键细节说明

  • patch('abc.ABC')会拦截xyz.py中from abc import ABC的导入逻辑,让它拿到的是Mock类而非原类。
  • mock_abc_cls.return_value对应Mock类实例化后的对象,也就是xyz.py里的obj,直接替换它的三个方法为MagicMock,就能完全控制方法的行为。
  • 必须在import xyz前完成所有Mock配置,否则原代码的实例化和方法调用已经执行,Mock会失去作用。

非测试场景的用法

如果不是在测试代码中,而是在业务脚本里需要Mock,也可以用类似方式:

from unittest.mock import patch, MagicMock

# 先创建Mock实例并配置方法
mock_obj = MagicMock()
mock_obj.__init__ = MagicMock()
mock_obj.print_1 = MagicMock()
mock_obj.print_2 = MagicMock()

# 替换abc.ABC为返回该Mock实例的Mock类
with patch('abc.ABC', return_value=mock_obj):
    import xyz

# 后续可以直接操作mock_obj,比如断言调用或修改返回值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 03:15:40