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

Python单元测试Mock失效:session_factory Mock未生效问题排查

问题原因与解决方法

问题根源

你的db.py模块在被导入时会立即执行所有顶层代码:包括实例化DatabaseSettings()、创建engine和session_factory。而测试中service.classA必然会导入db.py,这会在@patch生效之前就触发配置加载流程,导致mock根本来不及阻止配置初始化,所以依然会抛出环境变量缺失的异常。

解决方法

方案1:修改db.py,延迟初始化逻辑

将数据库初始化逻辑改为懒加载模式,避免顶层代码自动执行:

# db.py
class DatabaseSettings(BaseSettings):
    username: str
    password: str
    name: str
    host: str
    sql_echo: bool = False
    
    class Config(abc.Config):
        env_prefix = f"{abc.Config.env_prefix}DB_"
    
    def url(self):
        return f"mysql+aiomysql://{self.username}:{self.password}@{self.host}/{self.name}"

# 用函数封装初始化逻辑,需要时再调用
def get_session_factory():
    config = DatabaseSettings()
    engine = create_async_engine(config.url(), echo=config.sql_echo)
    return sessionmaker(engine, expire_on_commit=False, class_=AsyncSession)

之后在service.py中,改为通过get_session_factory()获取会话工厂,测试时直接mock这个函数即可。

方案2:在导入service前mock配置类

如果不想修改db.py结构,必须确保mock在service模块导入前生效:

@patch("config.db.DatabaseSettings")
@patch("config.db.session_factory")
@pytest.mark.asyncio
async def test_result(mock_session_factory, mock_db_settings):
    # 配置mock的DatabaseSettings返回假的数据库URL
    mock_config = mock_db_settings.return_value
    mock_config.url.return_value = "mysql+aiomysql://test:test@localhost/test_db"
    # 必须在mock完成后再导入service模块
    from service.classA import A1
    await A1()

方案3:用pytest fixture全局提前mock

将mock逻辑放到会话级fixture中,确保所有测试模块导入前完成mock:

import pytest
from unittest.mock import patch

@pytest.fixture(autouse=True, scope="session")
def mock_db_config():
    with patch("config.db.DatabaseSettings") as mock_db:
        mock_config = mock_db.return_value
        mock_config.url.return_value = "mysql+aiomysql://test:test@localhost/test_db"
        yield

@pytest.mark.asyncio
@patch("config.db.session_factory")
async def test_result(mock_session_factory):
    from service.classA import A1
    await A1()

关键提示

Python模块的顶层代码会在导入阶段立即执行,所有mock操作必须在这段代码执行前完成才能生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 19:13:27