Ayudh
Ayudh

Reputation: 1763

What approach should be used to test a SocketIO Client app using Jest?

I need to test a React Client app using SocketIO Client. I have searched various websites online but couldn't get any of their examples to work. I then installed Express on the client app as a dev dependency and tried to start a test server in the Jest test but couldn't get that to work.

So I was wondering, in fact, what would be the right way to test this app anyway?

My target is to test the following event listener registered in componentDidMount

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

Upvotes: 0

Views: 1822

Answers (1)

Lin Du
Lin Du

Reputation: 102457

Here is my solution:

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');
  });
});

Unit test result with 100% coverage:

 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

Source code: https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/58484558

Upvotes: 1

Related Questions