Files
ENI-projet-piscine/apps/backend/tests/conftest.py
T
Johan LEROY 3ca1866e93 test(backend): factorise les doubles de session
Chaque test reecrivait sa classe de session et sa fonction d'override, soit
trois fois le meme decor pour un seul endpoint. FakeSession et la fixture
fake_session portent ce decor, make_settings fabrique une Settings dont les
valeurs priment sur l'environnement.
2026-09-15 09:57:46 +02:00

67 lines
2.1 KiB
Python

import os
from collections.abc import AsyncIterator, Callable, Iterator
import pytest
from fastapi import FastAPI
from httpx import ASGITransport, AsyncClient
from app.core.config import get_settings
from app.db.session import get_engine, get_session, get_session_factory
from app.main import create_app
from tests.factories import FakeSession
# Piege : les variables d'environnement priment sur apps/backend/.env. Celles qu'on ne
# pose pas ici, c'est le .env du poste qui les decide, et les assertions avec.
@pytest.fixture(autouse=True, scope="session")
def environment() -> Iterator[None]:
os.environ.update(
{
"APP_ENV": "local",
"APP_DEBUG": "false",
"APP_LOG_LEVEL": "WARNING",
"APP_CORS_ORIGINS": "",
"APP_SECRET_KEY": "secret-de-test",
}
)
os.environ.setdefault(
"DATABASE_URL", "postgresql+asyncpg://enervision:change_me@localhost:5433/enervision_test"
)
get_settings.cache_clear()
yield
get_settings.cache_clear()
# Piege : get_engine est lru_cache et pytest-asyncio ouvre une boucle par test. Sans ce
# recyclage, le 2e test touchant vraiment la base heriterait d une boucle morte.
@pytest.fixture(autouse=True)
async def engine_per_test() -> AsyncIterator[None]:
yield
if get_engine.cache_info().currsize:
await get_engine().dispose()
get_engine.cache_clear()
get_session_factory.cache_clear()
@pytest.fixture
def app() -> FastAPI:
return create_app()
@pytest.fixture
async def client(app: FastAPI) -> AsyncIterator[AsyncClient]:
transport = ASGITransport(app=app)
async with AsyncClient(transport=transport, base_url="http://test") as async_client:
yield async_client
@pytest.fixture
def fake_session(app: FastAPI) -> Callable[..., None]:
def install(result: object = None, failure: Exception | None = None) -> None:
async def override() -> AsyncIterator[FakeSession]:
yield FakeSession(result=result, failure=failure)
app.dependency_overrides[get_session] = override
return install