覆盖 FastAPI 中的路由依赖

问题描述 投票:0回答:1

我正在使用FastAPI

我有路线:

@router.post("/product", tags=["product"])
async def create_product(request: Request,
                         id_generator: IdGenerator = Depends(get_id_generator)):

我有一个依赖文件。

def get_id_generator() -> IdGenerator:
    return UUIDIdGenerator()

我也有

SomeOtherIdGenerator
我想用于测试。我就是搞不懂。

@pytest.fixture
def test_id_generator():
    return SomeOtherIdGenerator()

@pytest.mark.asyncio
async def test_create_product(test_id_generator):
    data = '{ "a": "b" }'
    app.dependency_overrides['get_id_generator'] = lambda : test_id_generator

    client = TestClient(app)
    response = client.post("/product", json={'stuff': data})
    assert response.status_code == 201
    response_data = response.json()
    assert response_data['id'] == "some known value"

结果是我仍然得到一个UUID

Expected :'some known value'
Actual   :'06864d25-f88c-4382-9d1a-08c8e6951885'

我测试了有和没有

lambda

python testing dependencies overriding fastapi
1个回答
0
投票

您在示例中使用

app.dependency_overrides
属性的方式(即
app.dependency_overrides['get_id_generator'] = lambda : test_id_generator
)是错误,因为您传递的是
str
而不是 function 作为原始依赖项的键。传递一个
lambda
函数而不是另一个函数作为依赖覆盖的值。

根据 FastAPI 的文档

使用
app.dependency_overrides
属性

对于这些情况,您的 FastAPI 应用程序有一个属性

app.dependency_overrides
,很简单
dict

要覆盖测试的依赖项,您可以将原始的作为键 依赖项(函数),作为值,您的依赖项 覆盖(另一个功能

然后 FastAPI 将调用该覆盖而不是原来的 依赖性。

工作示例

from typing import Annotated
from fastapi import Depends, FastAPI
from fastapi.testclient import TestClient

app = FastAPI()


async def common_parameters(q: str | None = None, skip: int = 0, limit: int = 100):
    return {"q": q, "skip": skip, "limit": limit}


@app.get("/items")
async def read_items(commons: Annotated[dict, Depends(common_parameters)]):
    return {"message": "Hello Items!", "params": commons}


client = TestClient(app)


async def override_dependency(q: str | None = None):
    return {"q": q, "skip": 5, "limit": 10}


app.dependency_overrides[common_parameters] = override_dependency


def test_override_in_items():
    response = client.get("/items")
    assert response.status_code == 200
    assert response.json() == {
        "message": "Hello Items!",
        "params": {"q": None, "skip": 5, "limit": 10},
    }
© www.soinside.com 2019 - 2024. All rights reserved.