Override WebSocket Event Handling in Tests with MSW

In tests, mocking gives us a way to reproduce different network-related scenarios. Like in this lesson, we will create a runtime event handler for our WebSocket client messages to test a scenario when another user responds to a sent message in the chat.

Resources

Share with a coworker

Transcript

[00:00] I have another test case that starts much the same. I render the chat component using John as the test user, and then I send this message, hi everyone, in the chat. In response to this message, however, I want to send another message from a different user and make sure that the chat component can render them both at the same time. Because this is a network behavior specific to this particular test case, I will add it as an override using server.useApi. Similar to the HTTP handlers, I can use runtime handlers to add overwrites for my WebSocket event handling.

[00:35] So here I will use the same chat WebSocket link, add the connection listener, grab the client reference, and add the client.event listener or the message event. I want the intercepted message from John be printed in the UI so I will do client.sendEvent.data. Now I want another user to post a reply to this intercepted message. I will use client.send again and use the create chat message utility and provide us with these arguments, creating a mock message from Ashley that says, hi John, how are you? The only thing that's left now is to write our expectations, the assertions.

[01:20] So I'll head to the end of the test. I will first grab all the chat messages by screen, find all by role, and use log as the role and make sure that there are two chat messages. The first one that has text content that says hi everyone, this is the message from John, and the second one that has text content from Ashley that says, I'm just gonna copy it from here. Hi John, how are you? Now I will run this test and I can see that it's failing.

[01:59] If I take a closer look at Y, I can see that there are actually three chat messages being present. The first two are the ones we expect in this test case, but this other one, the third one, is unexpected. It's another Hi Everyone message from John. It gets rendered in the UI because of the happy path handling right here. In our handlers.yes, we also have a connection listener and a client message listener that prints all the intercepted messages in the chat.

[02:27] Because I don't need this logic to run in my new test case, I will head to this test case and to my runtime override over here, and I will call eventStopPropagation. By calling eventStopPropagation, I'm telling my test that I want to handle client messages only in this way and no other way. And because server.use will prepend my overrides, they will trigger first, effectively canceling the happy path behaviors. With the propagation stopped, I can see both test cases passing. Now when I send this message from John over here, hi everyone, it will get intercepted by this overwrite listener here, dispatch the message event on the client, stop any propagation to any other listeners for this message event, render the intercepted message in the UI and also have this different message from another user rendered as well, which we assert by the end of the test having these two different message assertions.