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

如何在pytest中Mock类实例?基于给定代码场景求助

问题描述

项目结构如下:

source
    main_proc.py
    devinstance.py
    prodinstance.py
    requirements.txt
    host.json

main_proc.py中的get_instance方法根据环境变量创建DevInstance或ProdInstance实例:

def get_instance(self):
    ins = None
    env = os.getenv('env', 'dev')
    if env == 'dev':
        ins = DevInstance()
    else:
        ins = ProdInstance()
    return ins

DevInstance类(devinstance.py)示例代码:

class DevInstance:
    def __init__(self):
        self.eh_client = dict()
        self.initialize()

    def initialize(self):
        try:
            client = EventHubProducerClient.from_connection_string(
                conn_str=self.secrets_dict[value],
                eventhub_name=names[i], 
                http_proxy=HTTP_PROXY
            )
        except Exception as e:
            logging.error(e)
            raise e

尝试测试get_instance时Mock整个DevInstance类实例,测试代码如下:

@mock.patch("devinstance.DevInstance")
def test_get_instance(self, devins):
    # Act
    devins.return_value = MagicMock()

    result = get_instance()

    # Assert
    assert result is not None

需要指导如何正确实现这一Mock操作?

正确Mock实现方案

1. 修正Mock路径

Python的Mock是基于被测试代码实际引用的对象路径生效的。get_instance在main_proc.py中导入并使用DevInstance,所以必须Mockmain_proc模块内的DevInstance引用,而非原始的devinstance.DevInstance。

修改装饰器路径:

@mock.patch("main_proc.DevInstance")

2. 简化Mock实例配置

mock.patch传入的参数(如mock_dev_class)本身就是类Mock对象,它的return_value默认就是MagicMock实例,无需手动赋值。如果需要定制Mock实例的属性/方法,直接操作return_value即可:

@mock.patch("main_proc.DevInstance")
def test_get_instance(self, mock_dev_class):
    # 可选:定制Mock实例的属性
    mock_instance = mock_dev_class.return_value
    mock_instance.eh_client = {"test_key": "test_value"}

    # 执行被测试方法
    result = get_instance()

    # 断言
    mock_dev_class.assert_called_once()  # 确认DevInstance被实例化一次
    assert result is mock_instance       # 确认返回的是Mock实例
    assert result is not None

3. 隔离环境变量影响

测试时建议临时设置环境变量,避免污染全局环境。可以用mock.patch.dict临时修改os.environ:

@mock.patch("main_proc.DevInstance")
@mock.patch.dict(os.environ, {'env': 'dev'})
def test_get_instance_dev(self, mock_dev_class):
    result = get_instance()
    mock_dev_class.assert_called_once()
    assert isinstance(result, MagicMock)

@mock.patch("main_proc.ProdInstance")
@mock.patch.dict(os.environ, {'env': 'prod'})
def test_get_instance_prod(self, mock_prod_class):
    result = get_instance()
    mock_prod_class.assert_called_once()
    assert isinstance(result, MagicMock)

4. 规避真实初始化逻辑

通过Mock整个DevInstance类,实例化时不会执行真实的__init__和initialize方法,完全用Mock替代,避免测试依赖外部资源(如EventHub连接)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 02:41:05