mocking / testing for socket.io-client in react app

Viewed 323

I have an issue with mocking / testing interactions with socket.io-client in my react application. I have tried methods such as mocking, libraries such as socket.io-mock and articles such as medium article. However, it did not came close to even emitting an event for my web application to consume.

socket_config.ts

import io from 'socket.io-client';
import config from '../utils/config';

const ws = io(config.socket_endpoint);

export default ws;

ScanPaperDocument.tsx

import React, { useState, useEffect } from 'react';
import ws from '../../socket';

const ScanPaperDocument: React.FC = () => {
  const [loading, setLoading] = useState<boolean>(true);
  const [scanning, setScanning] = useState<boolean>(true);

  useEffect(() => {
    ws.on('text_socket', (data: any) => {
      // Process the data, do some state change
      // Assuming that data is alright
      setLoading(false);
      setScanning(true);
    });

    ws.on('image_socket', (data: any) => {
      // Process the data, do some state change
    });
  }, []);

  return (
    <>
      {loading && scanning && <p>Scanning. Please wait.</p>}
      {!loading && scanning && <p>Here is your data.</p>}
      {/* And many other loading & scanning combinations */}
    </>
  );
};

export default ScanPaperDocument;

Here is a trashy mock implementation that I attempted to do ScanPaperDocument.test.tsx

import React from 'react';
import ScanPaperDocument from './ScanPaperDocument';
import { act, render, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

jest.mock('socket.io-client', () => {
  return jest.fn().mockImplementation(() => {
    return {
      on: jest.fn(),
      emit: jest.fn(),
    };
  });
});

describe(() => {
    it('is able to consume the incoming websocket event', () => {
        const { getByText } = render(<ScanPaperDocument />);
        
        // Not sure how do I 'emit' an event from the 'server' for my frontend to consume

        expect(getByText(/here is your data/i)).toBeTruthy();
    })
})

As for the medium article that I have attempted, I received the following error by simply calling serverSocket.emit('text_socket', {data: ''})

TypeError: Cannot read property 'forEach' of undefined

      2 |
      3 | const emit = (event, ...args) => {
    > 4 |   EVENTS[event].forEach((func) => func(...args));
        |                 ^
      5 | };
      6 |
      7 | const socket = {

      at Object.emit (src/socket/mock-socket.io-client.js:4:17)
0 Answers
Related