Coverage for tests / test_starlette_exception.py: 100%
53 statements
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-12 18:15 +0000
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-12 18:15 +0000
1from fastapi import FastAPI, HTTPException 1abcd
2from fastapi.testclient import TestClient 1abcd
3from inline_snapshot import snapshot 1abcd
4from starlette.exceptions import HTTPException as StarletteHTTPException 1abcd
6app = FastAPI() 1abcd
8items = {"foo": "The Foo Wrestlers"} 1abcd
11@app.get("/items/{item_id}") 1abcd
12async def read_item(item_id: str): 1abcd
13 if item_id not in items: 1kelfmg
14 raise HTTPException( 1efg
15 status_code=404,
16 detail="Item not found",
17 headers={"X-Error": "Some custom header"},
18 )
19 return {"item": items[item_id]} 1klm
22@app.get("/http-no-body-statuscode-exception") 1abcd
23async def no_body_status_code_exception(): 1abcd
24 raise HTTPException(status_code=204) 1qrs
27@app.get("/http-no-body-statuscode-with-detail-exception") 1abcd
28async def no_body_status_code_with_detail_exception(): 1abcd
29 raise HTTPException(status_code=204, detail="I should just disappear!") 1tuv
32@app.get("/starlette-items/{item_id}") 1abcd
33async def read_starlette_item(item_id: str): 1abcd
34 if item_id not in items: 1nhoipj
35 raise StarletteHTTPException(status_code=404, detail="Item not found") 1hij
36 return {"item": items[item_id]} 1nop
39client = TestClient(app) 1abcd
42def test_get_item(): 1abcd
43 response = client.get("/items/foo") 1klm
44 assert response.status_code == 200, response.text 1klm
45 assert response.json() == {"item": "The Foo Wrestlers"} 1klm
48def test_get_item_not_found(): 1abcd
49 response = client.get("/items/bar") 1efg
50 assert response.status_code == 404, response.text 1efg
51 assert response.headers.get("x-error") == "Some custom header" 1efg
52 assert response.json() == {"detail": "Item not found"} 1efg
55def test_get_starlette_item(): 1abcd
56 response = client.get("/starlette-items/foo") 1nop
57 assert response.status_code == 200, response.text 1nop
58 assert response.json() == {"item": "The Foo Wrestlers"} 1nop
61def test_get_starlette_item_not_found(): 1abcd
62 response = client.get("/starlette-items/bar") 1hij
63 assert response.status_code == 404, response.text 1hij
64 assert response.headers.get("x-error") is None 1hij
65 assert response.json() == {"detail": "Item not found"} 1hij
68def test_no_body_status_code_exception_handlers(): 1abcd
69 response = client.get("/http-no-body-statuscode-exception") 1qrs
70 assert response.status_code == 204 1qrs
71 assert not response.content 1qrs
74def test_no_body_status_code_with_detail_exception_handlers(): 1abcd
75 response = client.get("/http-no-body-statuscode-with-detail-exception") 1tuv
76 assert response.status_code == 204 1tuv
77 assert not response.content 1tuv
80def test_openapi_schema(): 1abcd
81 response = client.get("/openapi.json") 1wxy
82 assert response.status_code == 200, response.text 1wxy
83 assert response.json() == snapshot( 1wxy
84 {
85 "openapi": "3.1.0",
86 "info": {"title": "FastAPI", "version": "0.1.0"},
87 "paths": {
88 "/http-no-body-statuscode-exception": {
89 "get": {
90 "operationId": "no_body_status_code_exception_http_no_body_statuscode_exception_get",
91 "responses": {
92 "200": {
93 "content": {"application/json": {"schema": {}}},
94 "description": "Successful Response",
95 }
96 },
97 "summary": "No Body Status Code Exception",
98 }
99 },
100 "/http-no-body-statuscode-with-detail-exception": {
101 "get": {
102 "operationId": "no_body_status_code_with_detail_exception_http_no_body_statuscode_with_detail_exception_get",
103 "responses": {
104 "200": {
105 "content": {"application/json": {"schema": {}}},
106 "description": "Successful Response",
107 }
108 },
109 "summary": "No Body Status Code With Detail Exception",
110 }
111 },
112 "/items/{item_id}": {
113 "get": {
114 "responses": {
115 "200": {
116 "description": "Successful Response",
117 "content": {"application/json": {"schema": {}}},
118 },
119 "422": {
120 "description": "Validation Error",
121 "content": {
122 "application/json": {
123 "schema": {
124 "$ref": "#/components/schemas/HTTPValidationError"
125 }
126 }
127 },
128 },
129 },
130 "summary": "Read Item",
131 "operationId": "read_item_items__item_id__get",
132 "parameters": [
133 {
134 "required": True,
135 "schema": {"title": "Item Id", "type": "string"},
136 "name": "item_id",
137 "in": "path",
138 }
139 ],
140 }
141 },
142 "/starlette-items/{item_id}": {
143 "get": {
144 "responses": {
145 "200": {
146 "description": "Successful Response",
147 "content": {"application/json": {"schema": {}}},
148 },
149 "422": {
150 "description": "Validation Error",
151 "content": {
152 "application/json": {
153 "schema": {
154 "$ref": "#/components/schemas/HTTPValidationError"
155 }
156 }
157 },
158 },
159 },
160 "summary": "Read Starlette Item",
161 "operationId": "read_starlette_item_starlette_items__item_id__get",
162 "parameters": [
163 {
164 "required": True,
165 "schema": {"title": "Item Id", "type": "string"},
166 "name": "item_id",
167 "in": "path",
168 }
169 ],
170 }
171 },
172 },
173 "components": {
174 "schemas": {
175 "ValidationError": {
176 "title": "ValidationError",
177 "required": ["loc", "msg", "type"],
178 "type": "object",
179 "properties": {
180 "loc": {
181 "title": "Location",
182 "type": "array",
183 "items": {
184 "anyOf": [{"type": "string"}, {"type": "integer"}]
185 },
186 },
187 "msg": {"title": "Message", "type": "string"},
188 "type": {"title": "Error Type", "type": "string"},
189 "input": {"title": "Input"},
190 "ctx": {"title": "Context", "type": "object"},
191 },
192 },
193 "HTTPValidationError": {
194 "title": "HTTPValidationError",
195 "type": "object",
196 "properties": {
197 "detail": {
198 "title": "Detail",
199 "type": "array",
200 "items": {
201 "$ref": "#/components/schemas/ValidationError"
202 },
203 }
204 },
205 },
206 }
207 },
208 }
209 )