Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

287
Vistas
Typescript, React & Socket.io-client Tests

I'm trying to figure out how to write a Typescript/React app which uses socket.io to communicate to a server and thus other clients. However I'd like to write some tests in doing so.

In my sample app I have:

    import io, { Socket } from 'socket.io-client';
    
    const App = () => {
      let socket: Socket;
      const ENDPOINT = 'localhost:5000';
    
      const join = (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {
        event.preventDefault();
        socket = io(ENDPOINT);
        socket.emit('join', { name: 'Paola', room: '1' }, () => {});
      };
    
      return (
        <div className="join-container">
          <button className="join-button" onClick={join} data-testid={'join-button'}>
            Sign in
          </button>
        </div>
      );
    };
    
    export default App;

And my test looks like:

    import App from './App';
    import { render, screen, fireEvent } from '@testing-library/react';
    import 'setimmediate';
    
    
    describe('Join', () => {
      let mockEmitter = jest.fn();
      beforeEach(() => {
        jest.mock('socket.io-client', () => {
          const mockedSocket = {
            emit: mockEmitter,
            on: jest.fn((event: string, callback: Function) => {}),
          };
          return jest.fn(() => {
            return mockedSocket;
          }
            );
        });
      });
    
      afterEach(() => {
        jest.clearAllMocks();
      });
    
      it('joins a chat',  () => {
        // Arrange
        render(<App />);
    
        const btn =  screen.getByTestId('join-button');
    
        // Act
        fireEvent.click(btn);
    
        // Assert
        expect(btn).toBeInTheDocument();
        expect(mockEmitter).toHaveBeenCalled();
      });
    });

I just want to make sure I can mock socket.io-client so that I can verify that messages are being sent to the client and that it (later) reacts to messages sent in.

However the test is failing and it doesn't seem to be using my mock.

Error: expect(jest.fn()).toHaveBeenCalled()

Expected number of calls: >= 1
Received number of calls:    0
about 4 years ago · Santiago Gelvez
1 Respuestas
Responde la pregunta

0

In the manual-mocks#examples doc, there is a note:

Note: In order to mock properly, Jest needs jest.mock('moduleName') to be in the same scope as the require/import statement.

So, there are two solutions:

app.tsx:

import React from 'react';
import io, { Socket } from 'socket.io-client';

const App = () => {
  let socket: Socket;
  const ENDPOINT = 'localhost:5000';

  const join = (event: React.MouseEvent<HTMLButtonElement>) => {
    event.preventDefault();
    socket = io(ENDPOINT);
    socket.emit('join', { name: 'Paola', room: '1' }, () => {});
  };

  return (
    <div className="join-container">
      <button className="join-button" onClick={join} data-testid={'join-button'}>
        Sign in
      </button>
    </div>
  );
};

export default App;

Option 1: Call jest.mock and import ./app module in module scope of the test file.

app.test.tsx:

import App from './App';
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import React from 'react';

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

describe('Join', () => {
  afterEach(() => {
    jest.clearAllMocks();
  });

  it('joins a chat', () => {
    // Arrange
    render(<App />);
    const btn = screen.getByTestId('join-button');

    // Act
    fireEvent.click(btn);

    // Assert
    expect(btn).toBeInTheDocument();
    expect(mockEmitter).toHaveBeenCalled();
  });
});

Option 2: Since you call the jest.mock in beforeEach hook, require the './app' module in beforeEach hook function scope as well.

app.test.tsx:

import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import React from 'react';

describe('Join', () => {
  let mockEmitter = jest.fn();
  let App;
  beforeEach(() => {
    App = require('./app').default;
    jest.mock('socket.io-client', () => {
      const mockedSocket = {
        emit: mockEmitter,
        on: jest.fn(),
      };
      return jest.fn(() => mockedSocket);
    });
  });

  afterEach(() => {
    jest.clearAllMocks();
  });

  it('joins a chat', () => {
    // Arrange
    render(<App />);
    const btn = screen.getByTestId('join-button');

    // Act
    fireEvent.click(btn);

    // Assert
    expect(btn).toBeInTheDocument();
    expect(fakeEmitter).toHaveBeenCalled();
  });
});

package version:

"jest": "^26.6.3",
"ts-jest": "^26.4.4"

jest.config.js:

module.exports = {
  preset: 'ts-jest/presets/js-with-ts',
  testEnvironment: 'jsdom'
}
about 4 years ago · Santiago Gelvez Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda