ssnake
ssnake

Reputation: 236

Jest - How to mock RTCPeerConnection?

I need to test an ES6 class that initializes a RTCPeerConnection object inside his constructor. Something like this:

export class MyES6Class {
  protected conn: RTCPeerConnection;

  constructor() {
    this.conn = new RTCPeerConnection();
    this.conn.onconnectionstatechange = (event: Event) => this.onConnectionStateChange();
    this.conn.onicecandidate = (event: RTCPeerConnectionIceEvent) => this.onIceCandidate(event);

  ... other stuff...
  }
}

When I try to test this class, Jest complains that RTCPeerConnection is not defined.

Now, I've checked Jest documentation here on how to mock ES6 classes, but it only explains how to mock dependencies that are ES6 classes, while RTCPeerConnection is part of the browser (there is no need to import any module).

So, what is the proper way to mock RTCPeerConnection?

Upvotes: 1

Views: 2426

Answers (1)

Lin Du
Lin Du

Reputation: 102517

Here is a unit test solution:

index.ts:

export class MyES6Class {
  protected conn: RTCPeerConnection;

  constructor() {
    this.conn = new RTCPeerConnection();
    this.conn.onconnectionstatechange = (event: Event) => this.onConnectionStateChange();
    this.conn.onicecandidate = (event: RTCPeerConnectionIceEvent) => this.onIceCandidate(event);
  }

  private onConnectionStateChange() {
    console.log('onConnectionStateChange');
  }

  private onIceCandidate(event: RTCPeerConnectionIceEvent) {
    console.log('onIceCandidate');
  }
}

index.test.ts:

import { MyES6Class } from './';

describe('63011230', () => {
  it('should pass', () => {
    class TestMyES6Class extends MyES6Class {
      public testonconnectionstatechange(event) {
        this.conn.onconnectionstatechange!(event);
      }
      public testonicecandidate(event: RTCPeerConnectionIceEvent) {
        this.conn.onicecandidate!(event);
      }
    }
    const logSpy = jest.spyOn(console, 'log');
    (global as any).RTCPeerConnection = jest.fn();
    const instance = new TestMyES6Class();
    instance.testonconnectionstatechange({} as Event);
    instance.testonicecandidate({} as RTCPeerConnectionIceEvent);
    expect((global as any).RTCPeerConnection).toBeCalledTimes(1);
    expect(logSpy).toBeCalledWith('onConnectionStateChange');
    expect(logSpy).toBeCalledWith('onIceCandidate');
  });
});

unit test result with 100% coverage:

 PASS  stackoverflow/63011230/index.test.ts (15.4s)
  63011230
    ✓ should pass (23ms)

  console.log
    onConnectionStateChange

      at CustomConsole.<anonymous> (node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866:25)

  console.log
    onIceCandidate

      at CustomConsole.<anonymous> (node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866:25)

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

jest.config.js:

module.exports = {
  preset: 'ts-jest/presets/js-with-ts',
  testEnvironment: 'node',
  setupFilesAfterEnv: [
    './jest.setup.js',
  ],
  testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'],
  verbose: true,
};

source code: https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/63011230

Upvotes: 1

Related Questions