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

Python Mock问题:Mock方法外部依赖setup_logger时出错

问题根源

当测试文件执行from src.my_source import some_method时,Python会加载my_source.py模块,模块级代码logger = setup_logger()会立即执行真实的setup_logger函数。而原测试中的patch是在测试函数内部才生效,此时已经晚于模块加载的时机,真实函数被调用后触发了内部依赖的错误。

解决方案

必须在my_source模块被导入之前就完成setup_logger的Mock,以下是几种可行的实现方式:

方法1:使用pytest自动执行的Fixture

通过autouse=True的Fixture,在模块导入前启动patch:

from unittest.mock import patch
import pytest

@pytest.fixture(autouse=True)
def mock_setup_logger():
    with patch('src.my_source.setup_logger') as mock:
        # 给Mock设置返回值,模拟logger对象
        mock.return_value = mock.Mock()
        yield mock

# 此时导入模块,patch已经生效
from src.my_source import some_method

def test_some_method(mock_setup_logger):
    some_method()
    # 可选:验证函数是否被调用
    mock_setup_logger.assert_called_once()

方法2:在测试函数内部延迟导入模块

将模块导入放在测试函数内部,确保patch先启动:

from unittest.mock import patch
import pytest

@patch('src.my_source.setup_logger')
def test_some_method(mock_setup_logger):
    mock_setup_logger.return_value = mock.Mock()
    # 延迟导入,此时patch已生效
    from src.my_source import some_method
    some_method()
    mock_setup_logger.assert_called_once()

方法3:模块级Patch

在测试文件最顶部启动patch,覆盖整个测试模块的生命周期:

from unittest.mock import patch
import pytest

# 启动模块级patch
patch_obj = patch('src.my_source.setup_logger')
mock_setup_logger = patch_obj.start()
mock_setup_logger.return_value = mock.Mock()

# 导入模块,此时patch已生效
from src.my_source import some_method

def test_some_method():
    some_method()
    mock_setup_logger.assert_called_once()

# 测试完成后停止patch
def teardown_module():
    patch_obj.stop()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 12:35:31