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)