-
-
Notifications
You must be signed in to change notification settings - Fork 8.5k
Description
Description
Is it possible to disable or override middleware in unit tests?
Additional context
I have written some middleware to obtain a database pool connection and release it when the request is done. I'm using asyncpg directly for this as follows:
@app.middleware("http")
async def database_middleware(request: Request, call_next):
conn = None
try:
conn = await database_pool.acquire()
try:
await conn.fetch("SELECT 1")
except ConnectionDoesNotExistError:
conn = await database_pool.acquire()
request.state.db = conn
return await call_next(request)
except (PostgresConnectionError, OSError) as e:
logger.error("Unable to connect to the database: %s", e)
return Response(
"Unable to connect to the database.", status_code=HTTP_500_INTERNAL_SERVER_ERROR
)
except SyntaxOrAccessError as e:
logger.error("Unable to execute query: %s", e)
return Response(
"Unable to execute the required query to obtain data from the database.",
status_code=HTTP_500_INTERNAL_SERVER_ERROR,
)
finally:
if conn:
await database_pool.release(conn)I then have a little get_db dependency injection which is similar to the docs:
def get_db(request: Request):
return request.state.dbI'd like to mock my database in my unit tests so I can verify that I'm building the correct SQL given the appropriate params.
I've setup a pytest fixture to mock the database as follows:
@pytest.fixture(scope="function")
def db_mock(request):
def fin():
del app.dependency_overrides[get_db]
db_mock = mock.MagicMock()
app.dependency_overrides[get_db] = lambda: db_mock
request.addfinalizer(fin)
return db_mockThis works perfectly when the middleware is disabled. However, when it's enabled, naturally all endpoints fail with a 500 error as the database fails to connect.
After looking a little deeper into starlette codebase and the way middleware works, I couldn't seem to find an elegant way to disable or override middleware in my unit tests.
Any help is greatly appreciated. Also if you see anything wrong with the approach I'm taking, please do let me know.
Huge thanks!
Fotis