@@ -40,11 +40,11 @@ def app_environment(monkeypatch: pytest.MonkeyPatch) -> EnvVarsDict:
4040 )
4141
4242
43- async def test_setup_postgres_database_in_an_app (
44- is_pdb_enabled : bool ,
43+ @ pytest . fixture
44+ def app_lifespan (
4545 app_environment : EnvVarsDict ,
4646 mock_create_async_engine_and_database_ready : MockType ,
47- ):
47+ ) -> LifespanManager :
4848 assert app_environment
4949
5050 class AppSettings (BaseApplicationSettings ):
@@ -60,24 +60,28 @@ async def my_app_settings(app: FastAPI) -> AsyncIterator[State]:
6060 PostgresLifespanStateKeys .POSTGRES_SETTINGS : app .state .settings .CATALOG_POSTGRES
6161 }
6262
63- async def my_db_setup (app : FastAPI , state : State ) -> AsyncIterator [State ]:
63+ async def my_database_setup (app : FastAPI , state : State ) -> AsyncIterator [State ]:
6464 app .state .my_db_engine = state [PostgresLifespanStateKeys .POSTGRES_ASYNC_ENGINE ]
6565
66- assert (
67- app .state .my_db_engine
68- == mock_create_async_engine_and_database_ready .return_value
69- )
70-
7166 yield {}
7267
7368 # compose lifespans
7469 app_lifespan = LifespanManager ()
7570 app_lifespan .add (my_app_settings )
7671
77- postgres_lifespan .add (my_db_setup )
72+ postgres_lifespan .add (my_database_setup )
7873 app_lifespan .include (postgres_lifespan )
7974
80- # define app
75+ return app_lifespan
76+
77+
78+ async def test_setup_postgres_database_in_an_app (
79+ is_pdb_enabled : bool ,
80+ app_environment : EnvVarsDict ,
81+ mock_create_async_engine_and_database_ready : MockType ,
82+ app_lifespan : LifespanManager ,
83+ ):
84+
8185 app = FastAPI (lifespan = app_lifespan )
8286
8387 async with ASGILifespanManager (
@@ -103,6 +107,43 @@ async def my_db_setup(app: FastAPI, state: State) -> AsyncIterator[State]:
103107 ]
104108 )
105109
110+ assert (
111+ app .state .my_db_engine
112+ == mock_create_async_engine_and_database_ready .return_value
113+ )
114+
106115 # Verify that the engine was disposed
107116 async_engine : Any = mock_create_async_engine_and_database_ready .return_value
108117 async_engine .dispose .assert_called_once ()
118+
119+
120+ async def test_setup_postgres_database_dispose_engine_on_failure (
121+ is_pdb_enabled : bool ,
122+ app_environment : EnvVarsDict ,
123+ mock_create_async_engine_and_database_ready : MockType ,
124+ app_lifespan : LifespanManager ,
125+ ):
126+ expected_msg = "my_faulty_setup error"
127+
128+ def raise_error ():
129+ raise RuntimeError (expected_msg )
130+
131+ @app_lifespan .add
132+ async def my_faulty_setup (app : FastAPI , state : State ) -> AsyncIterator [State ]:
133+ assert PostgresLifespanStateKeys .POSTGRES_ASYNC_ENGINE in state
134+ raise_error ()
135+ yield {}
136+
137+ app = FastAPI (lifespan = app_lifespan )
138+
139+ with pytest .raises (RuntimeError , match = expected_msg ):
140+ async with ASGILifespanManager (
141+ app ,
142+ startup_timeout = None if is_pdb_enabled else 10 ,
143+ shutdown_timeout = None if is_pdb_enabled else 10 ,
144+ ):
145+ ...
146+
147+ # Verify that the engine was disposed even if error happend
148+ async_engine : Any = mock_create_async_engine_and_database_ready .return_value
149+ async_engine .dispose .assert_called_once ()
0 commit comments