Какой подход следует использовать для тестирования клиентского приложения SocketIO с использованием Jest? - PullRequest
0 голосов
/ 21 октября 2019

Мне нужно протестировать приложение React Client с помощью SocketIO Client. Я искал различные веб-сайты в Интернете, но не смог заставить работать их примеры. Затем я установил Express на клиентское приложение как зависимость от разработчика и попытался запустить тестовый сервер в тесте Jest, но не смог заставить его работать.

Так что мне было интересно, что на самом деле было бы правильным способом протестировать это приложение?

Моя цель - протестировать следующий прослушиватель событий, зарегистрированный в componentDidMount

componentDidMount() {
    const current_this = this;
    socket.on("numOfPlayersChanged", function(data) {
      // do something
    });
  }

1 Ответ

1 голос
/ 21 октября 2019

Вот мое решение:

index.tsx:

import React, { Component } from 'react';
import io from 'socket.io';

const socket = io();

class SomeComponent extends Component {
  constructor(props) {
    super(props);
    this.handleNumOfPlayersChanged = this.handleNumOfPlayersChanged.bind(this);
  }
  componentDidMount() {
    socket.on('numOfPlayersChanged', this.handleNumOfPlayersChanged);
  }
  render() {
    return <div>some component</div>;
  }

  handleNumOfPlayersChanged() {
    console.log('do something');
  }
}

export default SomeComponent;

index.spec.tsx:

import React from 'react';
import SomeComponent from './';
import { shallow } from 'enzyme';
import io from 'socket.io';

jest.mock('socket.io', () => {
  const mSocket = {
    on: jest.fn()
  };
  return jest.fn(() => mSocket);
});

describe('SomeComponent', () => {
  let wrapper;
  beforeEach(() => {
    wrapper = shallow(<SomeComponent></SomeComponent>);
    jest.restoreAllMocks();
  });
  test('should mount component and register socket event', () => {
    const instance = wrapper.instance() as any;
    const mSocket = io();
    expect(wrapper.text()).toBe('some component');
    expect(mSocket.on).toBeCalledWith('numOfPlayersChanged', instance.handleNumOfPlayersChanged);
  });

  test('should handle player changed ', () => {
    const logSpy = jest.spyOn(console, 'log');
    const instance = wrapper.instance() as any;
    instance.handleNumOfPlayersChanged();
    expect(logSpy).toBeCalledWith('do something');
  });
});

Результат модульного теста со 100% покрытием:

 PASS  src/stackoverflow/58484558/index.spec.tsx
  SomeComponent
    ✓ should mount component and register socket event (10ms)
    ✓ should handle player changed  (7ms)

  console.log node_modules/jest-mock/build/index.js:860
    do something

-----------|----------|----------|----------|----------|-------------------|
File       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files  |      100 |      100 |      100 |      100 |                   |
 index.tsx |      100 |      100 |      100 |      100 |                   |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        3.62s, estimated 8s

Исходный код: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58484558

...