starlette
starlette copied to clipboard
Disconnect event not received when using TestClient
Checklist
- [x] The bug is reproducible against the latest release and/or
master
. - [x] There are no similar issues or pull requests to fix it yet.
Describe the bug
When using the TestClient provided by the starlette framework, http.disconnect
are not received. This is a problem if trying to test streaming.
To reproduce
Implement simple app:
async def app(scope, receive, send):
await send({
'type': 'http.response.start',
'status': 200,
})
while True:
message = await receive()
print('message', message)
if message['type'] == 'http.disconnect':
break
Write test using provided TestClient, which closes the connection during "processing":
from bug import app
from starlette.testclient import TestClient
client = TestClient(app)
def test_client():
response = client.post('/', stream=True)
print('response.status', response.status)
response.close()
Expected behavior
The server behaviour should be the same if using TestClient or Uvicorn. If I run the application provided above with Uvicorn:
uvicorn bug:app
And write a test using the normal requests
as follows:
import requests
def test_server():
response = requests.post('http://localhost:8000/', stream=True)
print('response.status', response.status)
response.close()
The http.disconnect
event is received. This should be the same for the TestClient
Actual behavior
No http.disconnect
event is received by the app when using TestClient
.
Debugging material
Environment
- OS: Linux
- Python version: 3.8.10
- Starlette version: 0.16.0
Additional context
We should take care of this for https://github.com/encode/starlette/issues/652 , I guess.
I think this will always be a limitation of the TestClient
. I think we should add a test case, and maybe add a few lines on the documentation on how to test this.
A way to test an ASGI application with http.disconnect
without the TestClient
: https://github.com/encode/starlette/pull/1727