测试DBConnect时Mock sqlalchemy.create_engine失败,如何解决?
解决SQLAlchemy create_engine Mock失效问题
问题根源
你Mock的路径错了。Python的unittest.mock是针对代码中实际引用的对象路径生效的:
- DBConnect类里通过
from sqlalchemy import create_engine,已经把create_engine导入到catcom.db_connect模块中 - 直接Mock
sqlalchemy.create_engine不会影响到已经导入到目标模块里的create_engine实例,所以代码还是会调用真实的create_engine,触发实际数据库连接。
正确的Mock方式
把patch的目标改成catcom.db_connect.create_engine,也就是create_engine在DBConnect所在模块中的引用路径。
修改后的测试代码
from unittest import mock from catcom.db_connect import DBConnect # 用MagicMock简化模拟逻辑,无需手动编写MockEngine类 @mock.patch("catcom.db_connect.create_engine") def test_db_connect_initialization(mock_create_engine): # 模拟engine.connect()的返回值 mock_connection = mock.Mock() mock_create_engine.return_value.connect.return_value = mock_connection db = DBConnect("user", "pw", "127.0.0.1", "1234", "db") # 验证create_engine被正确调用,传入了预期的连接字符串 mock_create_engine.assert_called_once_with( "postgresql+psycopg2://user:pw@127.0.0.1:1234/db" ) # 验证connection属性是模拟的连接对象 assert db.connection == mock_connection
额外说明
- 路径规则:记住Mock的是被测试代码中实际使用的对象的导入路径,而非原始库的路径。如果代码里是
import sqlalchemy后用sqlalchemy.create_engine,才需要Mocksqlalchemy.create_engine。 - 简化模拟:用
unittest.mock.Mock或MagicMock可以省去手写模拟类的麻烦,直接通过设置return_value模拟方法调用结果。 - 增强验证:除了断言connection属性,还可以验证create_engine的调用参数,确保连接字符串生成逻辑正确。
内容的提问来源于stack exchange,提问作者Hans
相关产品推荐
相关产品推荐

