dependency_overrides cannot be used in tests as expected, documentation lacking
Describe the bug
Without fastapi-versioning, dependency_overrides can easily be specified on the app contained in the TestClient a la (pytest fixture like pseudo code):
before = client.app.dependency_overrides
client.app.dependency_overrides = dict(overrides)
try:
yield
finally:
client.app.dependency_overrides = before
With the internal use of sub application mounts, this doesn't work anymore and the override never reaches one of the versioned sub applications.
To Reproduce Steps to reproduce the behavior:
from fastapi import APIRouter, Depends, FastAPI
from fastapi.testclient import TestClient
from fastapi_versioning import versioned_api_route, VersionedFastAPI
app = FastAPI(title="test-app")
router = APIRouter(route_class=versioned_api_route(1, 0))
def dependency() -> str:
return "original"
@router.get("/test")
def get_test(dep: str = Depends(dependency)) -> str:
return dep
app.include_router(router)
app = VersionedFastAPI(app)
def test_this() -> None:
client = TestClient(app)
client.app.dependency_overrides = {dependency: lambda: "patched"}
assert client.get("/v1_0/test").json() == "patched"
This test will fail
Expected behavior
It should at least be documented how to access the correct sub application for providing the dependency_overrides.
Hello there...
Having the same issue here. Spent literally two days of trying to make tests work, to realize it's because of VersionedAPI... :( Anyone managed to find a workaround? It's basically impossible to attach a test database for testing purposes.
Thanks!
I was running into the same issue and realized it's caused by the order of operations:
- You create a FastAPI app
- You add routes with dependencies
- You create a VersionedFastAPI from the original app
- VersionedFastAPI creates a whole new FastAPI app (the versioned app) and for each version number, it takes all the routes from your original app that match that version number and attaches them to a new sub-app mounted on the versioned app
- You get back the versioned app
- You make a request to the versioned app
The issue is when you create the routes in step 2, they are "compiled" and still reference the original FastAPI app from step 1 even when the dependencies are resolved when you make a request in step 6, so you have to add the dependency overrides to the original app:
from fastapi import APIRouter, Depends, FastAPI
from fastapi.testclient import TestClient
from fastapi_versioning import versioned_api_route, VersionedFastAPI
original_app = FastAPI(title="test-app")
router = APIRouter(route_class=versioned_api_route(1, 0))
def dependency() -> str:
return "original"
@router.get("/test")
def get_test(dep: str = Depends(dependency)) -> str:
return dep
original_app.include_router(router)
app = VersionedFastAPI(original_app)
def test_this() -> None:
client = TestClient(app)
original_app.dependency_overrides = {dependency: lambda: "patched"}
assert client.get("/v1_0/test").json() == "patched"