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

如何在测试中引用FastAPI依赖,验证其下游传递正确性?

问题:验证FastAPI依赖的客户端是否正确传递给下游函数

现有FastAPI路由及依赖代码如下:

import httpx
from fastapi import FastAPI, Depends, Request

app = FastAPI()
router = app.router

async def get_client():
    try:
        client = httpx.AsyncClient()
        yield client

    finally:
        await client.aclose()


@router.get("/testendpoint")
async def get(
    http_req: Request,
    client: httpx.AsyncClient = Depends(get_client),
):
    return await call_external_api(client)


async def call_external_api(client: httpx.AsyncClient):
    return client.get("https://testapi/data")

编写测试时,无法直接引用依赖生成的客户端实例,验证它是否被正确传递给call_external_api:

from fastapi.testclient import TestClient
import pytest_mock

api_client = TestClient(app)

def test_get(mocker: pytest_mock.MockFixture):
    mock_func = mocker.patch("call_external_api")
    response = api_client.get("/testendpoint")
    mock_func.assert_called_once_with(client)  # client变量不存在,无法直接验证

解决方案

方法一:覆盖依赖,使用自定义可追踪的客户端实例

通过app.dependency_overrides替换原有的get_client依赖,返回预先创建的客户端实例,直接引用该实例做断言验证。

import httpx
from fastapi.testclient import TestClient
import pytest_mock
from your_module import app, get_client

api_client = TestClient(app)

def test_get_with_dependency_override(mocker: pytest_mock.MockFixture):
    # 创建自定义的客户端实例
    test_client = httpx.AsyncClient()
    # 覆盖依赖,让路由使用我们的实例
    app.dependency_overrides[get_client] = lambda: test_client
    
    # patch目标函数
    mock_func = mocker.patch("your_module.call_external_api")
    api_client.get("/testendpoint")
    
    # 验证调用时传入的是我们的自定义客户端
    mock_func.assert_called_once_with(test_client)
    
    # 测试后清理依赖覆盖,避免影响其他测试
    del app.dependency_overrides[get_client]

方法二:通过Mock的调用参数捕获验证

无需修改依赖,直接通过Mock对象的call_args属性获取实际传入的参数,验证其类型或特征。

from fastapi.testclient import TestClient
import pytest_mock
import httpx
from your_module import app

api_client = TestClient(app)

def test_get_with_call_args_validation(mocker: pytest_mock.MockFixture):
    mock_func = mocker.patch("your_module.call_external_api")
    api_client.get("/testendpoint")
    
    # 获取调用时传入的第一个位置参数
    called_client = mock_func.call_args[0][0]
    # 验证参数是httpx.AsyncClient实例
    assert isinstance(called_client, httpx.AsyncClient)
    # 若需验证客户端配置,可添加更多断言(比如base_url等)

进阶:验证客户端的具体调用行为

如果需要进一步验证客户端是否按预期调用了外部API,可直接patch客户端的get方法:

from fastapi.testclient import TestClient
import pytest_mock
from your_module import app

api_client = TestClient(app)

def test_external_api_call(mocker: pytest_mock.MockFixture):
    # patch httpx.AsyncClient的get方法
    mock_client_get = mocker.patch("httpx.AsyncClient.get")
    # 设置mock返回值
    mock_client_get.return_value = {"status": "ok", "data": "test"}
    
    api_client.get("/testendpoint")
    
    # 验证客户端调用了正确的API地址
    mock_client_get.assert_called_once_with("https://testapi/data")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:43:02