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

如何Mock Python脚本导入阶段调用的SQLAlchemy create_engine方法?

解决导入阶段执行的create_engine Mock问题

问题核心出在模块导入时机:database_wrapper.py里的engine = create_engine(...)是在模块被导入时立即执行的,你之前的所有patch操作都是在模块已经导入完成后才生效,自然无法拦截到初始的create_engine调用。要解决这个问题,必须保证mock在模块导入前就生效,同时选对patch的目标位置。

修正后的测试代码

from unittest import TestCase
from unittest.mock import patch, MagicMock

class TestMicroservice(TestCase):

    @patch('database_wrapper.create_engine')
    def test_1(self, create_engine_mock):
        # 1. 配置mock:给create_engine返回一个带connect方法的假引擎
        mock_engine = MagicMock()
        mock_connect = MagicMock()
        mock_engine.connect.return_value = mock_connect
        create_engine_mock.return_value = mock_engine

        # 2. 必须在patch生效后才导入目标模块
        from main import do_something
        do_something()

        # 3. 验证调用是否符合预期(可选)
        create_engine_mock.assert_called_once_with("connection_uri")
        mock_engine.connect.assert_called_once()

关键注意事项

  • 禁止提前导入目标模块:测试文件顶部绝对不能写import main或import database_wrapper,否则模块导入阶段create_engine已经执行,mock完全赶不上拦截时机。
  • 选对patch目标:因为database_wrapper里是from sqlalchemy import create_engine,相当于把create_engine复制到了database_wrapper的命名空间里,所以必须patchdatabase_wrapper.create_engine,而非sqlalchemy.create_engine或其他路径。
  • 补全mock的必要方法:原代码中update_database会调用engine.connect(),所以你的mock引擎必须模拟出connect方法(用MagicMock实现),否则运行时会触发属性不存在的报错。

如果你的测试目的只是验证do_something调用了update_database,可以保留@patch('main.update_database')的装饰器,但如果要测试update_database使用mock引擎的逻辑,就不能patch它,要让它真实执行,此时上面的代码完全适用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 14:33:20