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

如何Mock pymysqlpool.ConnectionPool构造函数?测试仍触发连接错误

问题解决:Mock pymysqlpool.ConnectionPool无效导致实际连接数据库

错误原因

你当前的@mock.patch('pymysqlpool.ConnectionPool')路径不对。Python的mock遵循**“在哪里使用就patch哪里”的原则:如果测试代码里直接从pymysqlpool导入ConnectionPool,需要patch的是测试模块自身中的ConnectionPool引用**,而非原库中的类。直接patch原库路径不会替换测试代码里已导入的类引用,导致实际构造函数仍被执行,触发数据库连接错误。

解决方案

1. 修正patch路径

假设你的测试文件名为test_db.py,且测试代码里是from pymysqlpool import ConnectionPool,把patch目标改成测试模块内的ConnectionPool:

@mock.patch(__name__ + '.ConnectionPool', autospec=True)

或者直接写模块名:

@mock.patch('test_db.ConnectionPool', autospec=True)

如果是测试业务代码(比如业务代码在myapp/db.py中导入并使用ConnectionPool),则需要patch业务模块中的引用:

@mock.patch('myapp.db.ConnectionPool', autospec=True)

2. 验证Mock是否生效(可选但推荐)

在测试方法中添加断言,确认Mock的构造函数被正确调用:

def test_load(self, connection_pool_mock: mock.Mock):
    ConnectionPool(
        size=2, maxsize=3, pre_create_num=2, host=os.environ["DATASOURCES_0_HOST"]
    )
    # 验证构造参数是否正确传递
    connection_pool_mock.assert_called_once_with(
        size=2, maxsize=3, pre_create_num=2, host="non-existent"
    )

修改后的完整测试代码

class DbTests(TestCase):
    @mock.patch(__name__ + '.ConnectionPool', autospec=True)
    @mock.patch.dict(
        os.environ,
        {
            "DATASOURCES_0_SERVERID": "server1",
            "DATASOURCES_0_HOST": "non-existent",
            "DATASOURCES_0_PORT": "3307",
            "DATASOURCES_0_DATABASE": "lj_ca1",
            "DATASOURCES_0_USERNAME": "sampleuser",
            "DATASOURCES_0_PASSWORD": "password1",
            "DATASOURCES_0_TIMEZONE": "Americas/Toronto",
        },
    )    
    def test_load(self, connection_pool_mock: mock.Mock):
        ConnectionPool(
            size=2, maxsize=3, pre_create_num=2, host=os.environ["DATASOURCES_0_HOST"]
        )
        # 断言Mock被正确调用
        connection_pool_mock.assert_called_once_with(
            size=2, maxsize=3, pre_create_num=2, host="non-existent"
        )

关键原理

Python的import会把模块中的对象引用缓存到导入者的命名空间里。你之前patch的是原库pymysqlpool中的ConnectionPool类,但测试代码里已经导入了该类的引用,这个引用不会因为原库的类被patch而改变。只有patch测试代码(或业务代码)命名空间里的那个ConnectionPool引用,才能替换掉实际使用的构造函数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 05:32:43