FastAPI - 将路由前缀添加到 TestClient

ss2*_*025 11 python starlette fastapi

我有一个 FastAPI 应用程序,其路由前缀为/api/v1.

当我运行测试时它会抛出404. 我发现这是因为TestClient无法找到 处的路线/ping,并且当测试用例中的路线更改为 时,它可以正常工作/api/v1/ping

有没有一种方法可以避免根据前缀更改所有测试函数中的所有路由?这似乎很麻烦,因为有很多测试用例,而且我不想在测试用例中对路由前缀进行硬编码依赖。TestClient有没有一种方法可以让我像在 中那样配置前缀app,并像在 中提到的那样简单地提及路由routes.py

路线.py

from fastapi import APIRouter

router = APIRouter()

@router.get("/ping")
async def ping_check():
    return {"msg": "pong"}
Run Code Online (Sandbox Code Playgroud)

主要.py

from fastapi import FastAPI
from routes import router

app = FastAPI()
app.include_router(prefix="/api/v1")
Run Code Online (Sandbox Code Playgroud)

在测试文件中我有:

测试.py

from main import app
from fastapi.testclient import TestClient

client = TestClient(app)

def test_ping():
    response = client.get("/ping")
    assert response.status_code == 200
    assert response.json() == {"msg": "pong"}
Run Code Online (Sandbox Code Playgroud)

ss2*_*025 5

为此找到了一个解决方法。

可以TestClient选择接受 a base_url,然后将其urljoin与路由一起使用path。所以我将路由前缀附加到了 this base_url

来源

url = urljoin(self.base_url, url)

然而,这有一个问题-urljoin仅当base_url以 a 结尾/且不以patha开头时才按预期连接/这个答案很好地解释了这一点。

这导致了以下变化:

测试.py

from main import app, ROUTE_PREFIX
from fastapi.testclient import TestClient

client = TestClient(app)
client.base_url += ROUTE_PREFIX  # adding prefix
client.base_url = client.base_url.rstrip("/") + "/"  # making sure we have 1 and only 1 `/`

def test_ping():
    response = client.get("ping")  # notice the path no more begins with a `/`
    assert response.status_code == 200
    assert response.json() == {"msg": "pong"}
Run Code Online (Sandbox Code Playgroud)