Skip to content

Commit 42deaca

Browse files
authored
Made WebsocketCommunicator assertions more informative. (#2098)
1 parent 8087d47 commit 42deaca

File tree

2 files changed

+36
-4
lines changed

2 files changed

+36
-4
lines changed

channels/testing/websocket.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,27 +78,33 @@ async def receive_from(self, timeout=1):
7878
"""
7979
response = await self.receive_output(timeout)
8080
# Make sure this is a send message
81-
assert response["type"] == "websocket.send"
81+
assert (
82+
response["type"] == "websocket.send"
83+
), f"Expected type 'websocket.send', but was '{response['type']}'"
8284
# Make sure there's exactly one key in the response
8385
assert ("text" in response) != (
8486
"bytes" in response
8587
), "The response needs exactly one of 'text' or 'bytes'"
8688
# Pull out the right key and typecheck it for our users
8789
if "text" in response:
88-
assert isinstance(response["text"], str), "Text frame payload is not str"
90+
assert isinstance(
91+
response["text"], str
92+
), f"Text frame payload is not str, it is {type(response['text'])}"
8993
return response["text"]
9094
else:
9195
assert isinstance(
9296
response["bytes"], bytes
93-
), "Binary frame payload is not bytes"
97+
), f"Binary frame payload is not bytes, it is {type(response['bytes'])}"
9498
return response["bytes"]
9599

96100
async def receive_json_from(self, timeout=1):
97101
"""
98102
Receives a JSON text frame payload and decodes it
99103
"""
100104
payload = await self.receive_from(timeout)
101-
assert isinstance(payload, str), "JSON data is not a text frame"
105+
assert isinstance(
106+
payload, str
107+
), f"JSON data is not a text frame, it is {type(payload)}"
102108
return json.loads(payload)
103109

104110
async def disconnect(self, code=1000, timeout=1):

tests/test_testing.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ def receive(self, text_data=None, bytes_data=None):
4747
self.send(text_data=text_data, bytes_data=bytes_data)
4848

4949

50+
class AcceptCloseWebsocketApp(WebsocketConsumer):
51+
def connect(self):
52+
assert self.scope["path"] == "/testws/"
53+
self.accept()
54+
self.close()
55+
56+
5057
class ErrorWebsocketApp(WebsocketConsumer):
5158
"""
5259
Barebones WebSocket ASGI app for error testing.
@@ -93,6 +100,25 @@ async def test_websocket_communicator():
93100
await communicator.disconnect()
94101

95102

103+
@pytest.mark.django_db
104+
@pytest.mark.asyncio
105+
async def test_websocket_incorrect_read_json():
106+
"""
107+
When using an invalid communicator method, an assertion error will be raised with
108+
informative message.
109+
In this test, the server accepts and then immediately closes the connection so
110+
the server is not in a valid state to handle "receive_from".
111+
"""
112+
communicator = WebsocketCommunicator(AcceptCloseWebsocketApp(), "/testws/")
113+
await communicator.connect()
114+
with pytest.raises(AssertionError) as exception_info:
115+
await communicator.receive_from()
116+
assert (
117+
str(exception_info.value)
118+
== "Expected type 'websocket.send', but was 'websocket.close'"
119+
)
120+
121+
96122
@pytest.mark.django_db
97123
@pytest.mark.asyncio
98124
async def test_websocket_application():

0 commit comments

Comments
 (0)