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

如何在Python单元测试中Mock SQLAlchemy的Query Filter?

解决SQLAlchemy Query Filter的Mock问题,让循环执行并转换行到字典

核心问题

UnifiedAlchemyMagicMock不会自动生成带数据的查询结果,需要手动配置链式调用的返回值,同时要模拟模型实例的__table__.columns属性(因为row2dict依赖该属性遍历列名)。

具体实现步骤及代码示例

以下是基于pytest的完整测试代码,包含模型定义、目标函数和Mock配置:

from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from alchemy_mock.mocking import UnifiedAlchemyMagicMock
import pytest
from unittest.mock import call

# 定义测试用的someModel(实际项目中直接导入即可)
Base = declarative_base()
class someModel(Base):
    __tablename__ = 'some_table'
    id = Column(Integer, primary_key=True)
    fileName = Column(String)

# 目标转换函数
def row2dict(row):
    d = {}
    for column in row.__table__.columns:
        d[column.name] = getattr(row, column.name)
    return d

def test_query_filter_mock():
    # 1. 创建模拟的模型行数据
    mock_row = someModel()
    mock_row.id = 1
    mock_row.fileName = "myfile"

    # 2. 模拟模型行的__table__.columns属性(row2dict依赖此遍历列名)
    mock_columns = [
        type('MockColumn', (), {'name': 'id'})(),
        type('MockColumn', (), {'name': 'fileName'})()
    ]
    mock_row.__table__ = type('MockTable', (), {'columns': mock_columns})()

    # 3. 配置UnifiedAlchemyMagicMock的链式调用返回值
    db = UnifiedAlchemyMagicMock()
    # 让filter返回包含模拟行的可迭代列表,确保for循环能执行
    db.query.return_value.filter.return_value = [mock_row]

    # 4. 执行目标业务代码
    data = db.query(someModel).filter(someModel.fileName == "myfile")
    result_list = []
    for row in data:
        a = row2dict(row)
        result_list.append(a)

    # 验证结果正确性
    assert result_list == [{'id': 1, 'fileName': 'myfile'}]
    # 验证Query和Filter的调用是否符合预期
    db.query.assert_called_once_with(someModel)
    db.query.return_value.filter.assert_called_once_with(
        someModel.fileName == "myfile"
    )

关键说明

  • 模拟可迭代结果:必须让filter方法返回包含模拟行的列表(或其他可迭代对象),否则for循环会因无数据跳过。
  • 模拟__table__.columns:row2dict通过遍历该属性获取列名,若不模拟会抛出AttributeError,这里用动态类模拟列对象的name属性即可满足需求。
  • 条件匹配验证:通过assert_called_once_with可以验证Filter是否使用了预期的查询条件,确保Mock的准确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 17:45:22