robtaussig / react-use-websocket

React Hook for WebSocket communication
MIT License
1.63k stars 135 forks source link

How to mock lastJsonMessage using Jest #75

Closed alduro closed 3 years ago

alduro commented 3 years ago

Hi, I have this code

  const getToken = useCallback(async () => {
    const requestOptions = {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': '*',
        'X-CSRF-Token': csrfToken,
      },
    };

    const response = await fetch(`/current_users/token`, requestOptions);

    try {
      const { token } = await response.json();
      return token;
    } catch (e) {
      return { status: 500, error: e.message };
    }
  }, [csrfToken]);

  const getWssUrl = useCallback(async () => {
    const token = await getToken();
    return `${wssURL}?token=${token}`;
  }, [getToken, wssURL]);

  const { sendJsonMessage, lastJsonMessage } = useWebSocket(getWssUrl, {
    onOpen: () => sendJsonMessage({ action: 'notify' }),
    share: true,
    shouldReconnect: () => true,
  });
  ...

  useEffect(() => {
    lastJsonMessage && handleReceiveMessage(lastJsonMessage.data);
  }, [lastJsonMessage]);

and I was wondering how should I mock lastJsonMessge in a test ?

Thanks in advance.

robtaussig commented 3 years ago

Hi @alduro,

lastJsonMessage is generated with the following:

  const lastJsonMessage = useMemo(() => {
    if (lastMessage) {
      try {
        return JSON.parse(lastMessage.data);
      } catch (e) {
        return UNPARSABLE_JSON_OBJECT;
      }
    }
    return null;
  },[lastMessage]);

UNPARSABLE_JSON_OBJECT is a static empty object. So where no message has been received from the websocket server, lastJsonMessage will be null -- otherwise it will be a JSON-parsed representation of the message (or an empty object if the message isn't parsable). As far as mocking it, that depends on how you are mocking the websocket connection in jest -- I recommend jest-websocket-mock. You can see how I test the library here.

robtaussig commented 3 years ago

Specifically, here is testing lastJsonMessage:

https://github.com/robtaussig/react-use-websocket/blob/94fc42c66fb24f3ca9533f897fb884fa9ad7a496/src/lib/use-websocket.test.ts#L104-L115