python - 如何在 Python 3 单元测试中模拟“with connect”SQL 查询?
问题描述
对于像下面这样的函数,其中引擎是 SQLAlchemy 引擎,例如,
from sqlalchemy import create_engine
engine = create_engine(f'mysql+pymysql://{db_username}:{db_password}@{db_host}:{db_port}/{db_name}', pool_recycle=3600)
def pull(engine, afield):
query = f"SELECT col1, col2 FROM mydatabase WHERE field='{afield}'"
with engine.connect() as conn:
result = conn.execute(query)
return result
如何模拟单元测试中“with”语句的查询结果?
解决方案
假设上述函数datapull.py
位于与本单元测试代码命名并位于同一目录的文件中,那么下面是一个模拟 SQL 结果的示例。
模拟引擎和连接相当简单,但模拟引擎返回连接则比较棘手。
with 语句(此处__enter__
针对 Python 3 进行了描述)在引擎上调用后返回连接。
因此mock_engine.connect.return_value.__enter__.return_value = mock_conn
将在上述代码的 with 语句中正确返回模拟连接。
import mock
import unittest
import datapull
class TestQueryRDS(unittest.TestCase):
def test_happy_day(self):
"""Test happy day query"""
mock_conn = mock.MagicMock()
mock_conn.execute.return_value = [['c1', 'c2'], ['a1', 'a2']]
mock_engine = mock.MagicMock()
mock_engine.connect.return_value.__enter__.return_value = mock_conn
actual = datapull.pull(mock_engine, '1234abcd')
assert actual == [['c1', 'c2'], ['a1', 'a2']]
exp_sql = "SELECT col1, col2 FROM mydatabase WHERE field='1234abcd'"
mock_conn.execute.assert_called_once_with(exp_sql)
推荐阅读
- python - 加入两个数据框并用熊猫填充值
- angular - ngStyle 仅在 F5 后应用(刷新)
- php - 升级到 laravel 7 后是否需要移动 auth 脚手架?
- amazon-web-services - 无法连接到在 Docker 上运行的 Amazon Redshift 的本地实例
- django - 如何访问模板中的模型字段详细名称?
- reactjs - 如何强制 useEffect 等到其他组件收到数据?
- flutter - 将 OnPressed 操作添加到小部件颤动
- python - 提取特定字符之前的单词
- php - PHP函数来编辑标题标签wordpress
- javascript - 无法将八位字节流的响应数据转换为 Zip 文件并下载