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

如何编写pytest模拟Flask路由中的数据库连接与查询结果?

用pytest测试Flask路由并Mock数据库连接与查询

问题背景

我有如下Flask应用路由代码:

# routes.py

from flask import jsonify
from app.utils.db import db_connection, db_query
from typing import List, Dict  # 补充缺失的类型导入

@api.route("/some/route", methods=["GET"])
@auth
def get_data_for_some_route(**kwargs) -> List[Dict]:

    # connect to db
    db_client = db_connection()
 
    # Query db for data(注:原代码里的db.query应为db_query函数的笔误)
    data = db_query(db_client, GET_STUFF)

    # parse the data example
    parsed_data = data[0]
    
    return jsonify(parsed_data), 200

我想编写pytest测试该路由,同时Mock数据库连接与查询结果,目前写了如下测试代码但仍有困惑:

# test_routes.py

import pytest
from fixtures import SOME_ROUTE_JSON_DATA
from json import loads  # 补充缺失的导入

mock_token = "12345"

def test_get_data_for_some_route(mocker, client):
    querystring1 = 'Hello'
    querystring2 = 'World'

    # Mock db query function
    mocked_db_query = mocker.patch('app.utils.database.db_connection')
    mocked_db_query.return_value = loads(SOME_ROUTE_JSON_DATA)

    # Call the route
    response = client.get(
        f"/some_route",
        headers={"Authorization": f"{mock_token}"}
    )

    # assert response.json is some value I expect it to be

我不清楚如何在路由内Mock值,希望能忽略数据库连接,指定测试时的返回数据,从而继续测试函数逻辑。


解决方法

1. 明确Mock的正确路径

Mock的核心原则是patch被测试代码实际使用的对象引用,而非原模块路径。路由代码从app.utils.db导入了db_connection和db_query,因此需要patch这两个对象在routes模块中的引用,即app.routes.db_connection和app.routes.db_query。

2. 分别Mock数据库连接与查询

  • 数据库连接db_connection只需返回一个无关紧要的假对象即可,后续查询操作会被Mock覆盖。
  • 查询函数db_query需要设置return_value为预设的测试数据,确保路由内的data变量拿到我们指定的值,从而测试后续解析逻辑。

3. 修正请求路径与细节

路由实际路径是/some/route,测试中的/some_route是错误的,需修正;同时确保@auth装饰器能识别传入的mock_token,若认证逻辑也需Mock,可额外patch认证装饰器。

完整测试代码示例

# test_routes.py

import pytest
from fixtures import SOME_ROUTE_JSON_DATA
from json import loads

mock_token = "12345"
# 预设测试用的查询返回数据
TEST_DB_DATA = [{"id": 1, "name": "test_sample"}]

def test_get_data_for_some_route(mocker, client):
    # 1. Mock数据库连接,返回假客户端对象
    mock_db_conn = mocker.patch("app.routes.db_connection")
    mock_db_conn.return_value = "fake_db_client"  # 任意值均可

    # 2. Mock查询函数,返回预设测试数据
    mock_db_query = mocker.patch("app.routes.db_query")
    mock_db_query.return_value = TEST_DB_DATA

    # 3. 发起正确路径的请求
    response = client.get(
        "/some/route",
        headers={"Authorization": f"{mock_token}"}
    )

    # 4. 断言响应状态码与返回值
    assert response.status_code == 200
    assert response.json == TEST_DB_DATA[0]  # 与路由内的解析逻辑对应

    # 可选:验证Mock对象是否被正确调用
    mock_db_conn.assert_called_once()
    mock_db_query.assert_called_once_with("fake_db_client", "GET_STUFF")  # 匹配GET_STUFF常量

关键说明

  • 如果路由内的db.query是调用某个db对象的方法(而非导入的db_query函数),需调整Mock对象:比如从app.utils.db import db的话,要patchapp.routes.db.query,并设置mock_query.return_value = TEST_DB_DATA。
  • 通过Mock数据库相关操作,可完全隔离真实数据库,仅测试路由的业务逻辑(数据解析、响应返回)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 02:23:11