Saket Kumar
Saket Kumar

Reputation: 73

Jest React: How to mock window eventListener set in componentDidMount

Here I need to add tests for handleBeforeUnload in window eventListener but I am getting error, How will I resolve it?

   expect(jest.fn())[.not].toHaveBeenCalled()

    Matcher error: received value must be a mock or spy function

    Received has value: undefined

    map.beforeunload();
    
   expect(wrapper.handleBeforeUnload).toHaveBeenCalled();

My component

componentDidMount() {
       window.addEventListener('beforeunload', (event) => {
      this.handleBeforeUnload();
    });
}

handleBeforeUnload () {
}

My test spec:

  it('should call handleBeforeUnload', () => {
    const historyMock = { listen: jest.fn(), replace: jest.fn() };
    const map = {};
    window.addEventListener = jest.fn((event, cb) => {
      map[event] = cb;
    });
    const wrapper = shallow(
      <AppRoutes history={historyMock} getDctkConfig={getDctkConfig} />,
    );

    map.beforeunload();

    expect(wrapper.handleBeforeUnload).toHaveBeenCalled();

  });

Upvotes: 0

Views: 1946

Answers (1)

Lin Du
Lin Du

Reputation: 102672

You didn't spy the.handleBeforeUnload() method of the component class. You can spy it through Component.prototype.handleBeforeUnload. Besides, you can mock the implementation of the .addEventListener() method and invoke the listener function manually.

index.tsx:

import React, { Component } from 'react';

export default class AppRoutes extends Component {
  componentDidMount() {
    window.addEventListener('beforeunload', (event) => {
      this.handleBeforeUnload();
    });
  }

  handleBeforeUnload() {}

  render() {
    return <div>app routes</div>;
  }
}

index.test.tsx:

import { shallow } from 'enzyme';
import React from 'react';
import AppRoutes from './';

describe('69346085', () => {
  afterEach(() => {
    jest.restoreAllMocks();
  });
  test('should pass', () => {
    const handleBeforeUnloadSpy = jest.spyOn(AppRoutes.prototype, 'handleBeforeUnload');
    jest
      .spyOn(window, 'addEventListener')
      .mockImplementation((type: string, listener: EventListenerOrEventListenerObject) => {
        typeof listener === 'function' && listener({} as Event);
      });
    shallow(<AppRoutes />);

    expect(handleBeforeUnloadSpy).toHaveBeenCalled();
  });
});

test result:

PASS  examples/69346085/index.test.tsx (9.191 s)
  69346085
    ✓ should pass (7 ms)

-----------|---------|----------|---------|---------|-------------------
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:       1 passed, 1 total
Snapshots:   0 total
Time:        9.814 s, estimated 10 s

Upvotes: 1

Related Questions