Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
520 views
in Technique[技术] by (71.8m points)

reactjs - How to mock a constructor used in React componentWillUnmount

I'm trying to test React component with mapbox-gl and using Jest and react-testing-library. Inside Component, I'm using mapbox constructor and assigning an instance to this.map In componentWillUnmount calling this.map.remove() and it leads to error in test.

Code of the component

import React, { Component } from "react";
import mapboxgl from "mapbox-gl";
import "./Map.css";

class Map extends Component {
  constructor(props) {
    super(props);
    this.map = null;
    this.mapContainer = React.createRef();
  }

  componentDidMount() {
    this.map = new mapboxgl.Map({
      container: this.mapContainer.current,
      style: "mapbox://styles/mapbox/streets-v11",
      center: [37.61513, 55.7513461], 
      zoom: 11,
    });
  }

  componentWillUnmount() {
    this.map.remove();
  }

  render() {
    return (
      <div
        data-testid="map"
        className="map-container"
        ref={this.mapContainer}
      />
    );
  }
}

export default Map;

Trying to test it e.g:

import Map from "../../page/Map/Map";
import React from "react";
import renderer from "react-test-renderer";
import { render } from '@testing-library/react'
import mapboxgl from "mapbox-gl";

jest.mock('mapbox-gl', () => ({
    Map: jest.fn(() => ({
        remove: jest.fn()
    })),
}));

describe('Map.js', () => {    
    it('should call mapbox-gl', function () {
        const { getByTestId } = render( <Map />);
        expect(mapboxgl.Map).toHaveBeenCalledWith({
            container: getByTestId('map'),
            style: "mapbox://styles/mapbox/streets-v11",
            center: [37.61513, 55.7513461],
            zoom: 11,
        });
    });
})

And got this error:

Map.js ? should call mapbox-gl

TypeError: this.map.remove is not a function

  22 |
  23 |   componentWillUnmount() {
> 24 |     this.map.remove();
     |              ^
  25 |   }
  26 |
  27 |   render() {
question from:https://stackoverflow.com/questions/65560085/how-to-mock-a-constructor-used-in-react-componentwillunmount

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

As per jest docs ,

jest.fn() Returns a new, unused mock function. Optionally takes a mock implementation.

enter image description here

jest.fn() rerurns is spy function which doesn't have a constructor, so you won't be able to create object for (mapbox-gl.Map) with new, thus there's no properties called remove or etc..

jest.mock('mapbox-gl', () => ({
    Map: jest.fn(() => ({ -> is mocked function and it doesn't have a constructor 
        remove: jest.fn()
    })),
}));

To mock modules, you need to use jest.mock, something like below.

jest.mock('mapbox-gl') will automatically mocks the properties of mapbox-gl and returns a wrapped spies object.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...