如何使用 Jest + Enzyme 测试 google maps 函数是否在 componentDidUpdate() 上运行?

How to test if google maps function runs on componentDidUpdate() with Jest + Enzyme?

我对 Jest 和 Enzyme 的 TDD 还是个新手,在尝试测试我的 google 地图组件时遇到了 运行 问题。

组件从我的 API 接收 GeoJson 数据作为道具,该数据可能会发生变化,因此初始化函数应该 运行 on componentDidUpdate()

Map.js

import React, { Component } from 'react';

class Map extends Component {
    initMap = () => {
        const el = document.getElementById("map-js");

        const options = {
            center: {
                lat: -27.9959656,
                lng: 153.2879044,
            },
            zoom: 9
        };

        const map = new window.google.maps.Map(el, options);
        map.data.addGeoJson(this.props.data);
    };

    componentDidUpdate(){
        this.initMap();
    };

    render() {
        return(
            <div className="map__holder">
                <div id="map-js"></div>
            </div>
        );
    };
};

export default Map;

我正在尝试编写一个测试来检查 initMap 函数 运行 是否在 props 更改时成功。

我不确定将道具传递给我的浅层渲染的最佳方式,所以我只使用了 Json 文件中的第一个值。下面是我的测试。

当我 运行 时,我不断收到此错误“类型错误:无法读取未定义的 属性 'maps'”

任何人都可以提供有关通过此测试的任何建议吗?

Map.test.js

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

it("runs init map on component update", () => {
    const props = {
        "type": "FeatureCollection",
        "totalFeatures": 1,
        "features": [{
            "type": "Feature",
            "id": "af1b8d1c_a186_4e72_8e9e_549a8065e970.1",
            "geometry": {
                "type": "MultiPolygon",
                "coordinates": [
                    [
                        [
                            [153.29237339772322, -27.897575560605485],
                            [153.29240999654635, -27.897600934719307],
                            [153.29243164508424, -27.897612892477547],
                            [153.29242807749804, -27.89762571619733],
                            [153.2924182348173, -27.897642434997323],
                            [153.29240518208437, -27.89764887031301],
                            [153.29238402481764, -27.897632940370542],
                            [153.29236010912982, -27.897619001393466],
                            [153.29233897564296, -27.8976119164061],
                            [153.29237339772322, -27.897575560605485]
                        ]
                    ]
                ]
            },
            "geometry_name": "geom",
            "properties": {
                "rec_id": 1598139,
                "status": "CURRENT",
                "asset_numb": "BOAR320",
                "type": "Boat Ramp",
                "material": "Gravel",
                "number_lan": 1,
                "add_improv": "f",
                "top_rl": 0,
                "toe_rl": 0,
                "area_": 36.079,
                "comments": "Council use only",
                "documents": "../photos/31/j31p6.jpg",
                "inspectors": null,
                "inspection": "2009-09-23Z",
                "constructi": null,
                "record_cre": "2007-04-27Z",
                "last_updat": null,
                "update_dat": "2011-07-22Z",
                "disposal_d": null,
                "positional": "GPS Corrected 1.0M",
                "level_accu": null,
                "owner": "251",
                "project_nu": null,
                "file_numbe": null,
                "folder_num": null,
                "drawing_nu": null,
                "survey_num": null,
                "condition": 4,
                "historic_c": 0,
                "funding_ba": "Non GCCC",
                "mi_symbolo": "Pen (2, 2, 65535) Brush (1, 0, 16777215)",
                "mi_prinx": 1598139,
                "createuser": null,
                "createdate": null,
                "updateuser": null,
                "updatedate": null,
                "shape_leng": 25.1301720763,
                "shape_area": 36.0791723381
            }
        }]
    };

    const updatedProps = {
        "type": "FeatureCollection",
        "totalFeatures": 2, //value changed in updated props
        "features": [{
            "type": "Feature",
            "id": "af1b8d1c_a186_4e72_8e9e_549a8065e970.1",
            "geometry": {
                "type": "MultiPolygon",
                "coordinates": [
                    [
                        [
                            [153.29237339772322, -27.897575560605485],
                            [153.29240999654635, -27.897600934719307],
                            [153.29243164508424, -27.897612892477547],
                            [153.29242807749804, -27.89762571619733],
                            [153.2924182348173, -27.897642434997323],
                            [153.29240518208437, -27.89764887031301],
                            [153.29238402481764, -27.897632940370542],
                            [153.29236010912982, -27.897619001393466],
                            [153.29233897564296, -27.8976119164061],
                            [153.29237339772322, -27.897575560605485]
                        ]
                    ]
                ]
            },
            "geometry_name": "geom",
            "properties": {
                "rec_id": 1598139,
                "status": "CURRENT",
                "asset_numb": "BOAR320",
                "type": "Boat Ramp",
                "material": "Gravel",
                "number_lan": 1,
                "add_improv": "f",
                "top_rl": 0,
                "toe_rl": 0,
                "area_": 36.079,
                "comments": "Council use only",
                "documents": "../photos/31/j31p6.jpg",
                "inspectors": null,
                "inspection": "2009-09-23Z",
                "constructi": null,
                "record_cre": "2007-04-27Z",
                "last_updat": null,
                "update_dat": "2011-07-22Z",
                "disposal_d": null,
                "positional": "GPS Corrected 1.0M",
                "level_accu": null,
                "owner": "251",
                "project_nu": null,
                "file_numbe": null,
                "folder_num": null,
                "drawing_nu": null,
                "survey_num": null,
                "condition": 4,
                "historic_c": 0,
                "funding_ba": "Non GCCC",
                "mi_symbolo": "Pen (2, 2, 65535) Brush (1, 0, 16777215)",
                "mi_prinx": 1598139,
                "createuser": null,
                "createdate": null,
                "updateuser": null,
                "updatedate": null,
                "shape_leng": 25.1301720763,
                "shape_area": 36.0791723381
            }
        }]
    };

    const wrapper = shallow(<Map data={props} />);
    const spy = jest.spyOn(wrapper.instance(), 'initMap');

    wrapper.setProps({data: updatedProps});

    expect(spy).toBeCalled();
});

您应该在 运行 测试之前将模拟的 google 变量分配给 window

例如

Map.js:

import React, { Component } from 'react';

class Map extends Component {
  initMap = () => {
    const el = document.getElementById('map-js');
    const options = {
      center: {
        lat: -27.9959656,
        lng: 153.2879044,
      },
      zoom: 9,
    };

    const map = new window.google.maps.Map(el, options);
    map.data.addGeoJson(this.props.data);
  };

  componentDidUpdate() {
    this.initMap();
  }

  render() {
    return (
      <div className="map__holder">
        <div id="map-js"></div>
      </div>
    );
  }
}

export default Map;

Map.test.js:

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

describe('64635170', () => {
  it('should pass', () => {
    const props = {
      type: 'FeatureCollection',
      totalFeatures: 1,
      features: [
        {
          type: 'Feature',
          id: 'af1b8d1c_a186_4e72_8e9e_549a8065e970.1',
          geometry: {
            type: 'MultiPolygon',
            coordinates: [
              [
                [
                  [153.29237339772322, -27.897575560605485],
                  [153.29240999654635, -27.897600934719307],
                  [153.29243164508424, -27.897612892477547],
                  [153.29242807749804, -27.89762571619733],
                  [153.2924182348173, -27.897642434997323],
                  [153.29240518208437, -27.89764887031301],
                  [153.29238402481764, -27.897632940370542],
                  [153.29236010912982, -27.897619001393466],
                  [153.29233897564296, -27.8976119164061],
                  [153.29237339772322, -27.897575560605485],
                ],
              ],
            ],
          },
          geometry_name: 'geom',
          properties: {
            rec_id: 1598139,
            status: 'CURRENT',
            asset_numb: 'BOAR320',
            type: 'Boat Ramp',
            material: 'Gravel',
            number_lan: 1,
            add_improv: 'f',
            top_rl: 0,
            toe_rl: 0,
            area_: 36.079,
            comments: 'Council use only',
            documents: '../photos/31/j31p6.jpg',
            inspectors: null,
            inspection: '2009-09-23Z',
            constructi: null,
            record_cre: '2007-04-27Z',
            last_updat: null,
            update_dat: '2011-07-22Z',
            disposal_d: null,
            positional: 'GPS Corrected 1.0M',
            level_accu: null,
            owner: '251',
            project_nu: null,
            file_numbe: null,
            folder_num: null,
            drawing_nu: null,
            survey_num: null,
            condition: 4,
            historic_c: 0,
            funding_ba: 'Non GCCC',
            mi_symbolo: 'Pen (2, 2, 65535) Brush (1, 0, 16777215)',
            mi_prinx: 1598139,
            createuser: null,
            createdate: null,
            updateuser: null,
            updatedate: null,
            shape_leng: 25.1301720763,
            shape_area: 36.0791723381,
          },
        },
      ],
    };

    const updatedProps = {
      type: 'FeatureCollection',
      totalFeatures: 2, //value changed in updated props
      features: [
        {
          type: 'Feature',
          id: 'af1b8d1c_a186_4e72_8e9e_549a8065e970.1',
          geometry: {
            type: 'MultiPolygon',
            coordinates: [
              [
                [
                  [153.29237339772322, -27.897575560605485],
                  [153.29240999654635, -27.897600934719307],
                  [153.29243164508424, -27.897612892477547],
                  [153.29242807749804, -27.89762571619733],
                  [153.2924182348173, -27.897642434997323],
                  [153.29240518208437, -27.89764887031301],
                  [153.29238402481764, -27.897632940370542],
                  [153.29236010912982, -27.897619001393466],
                  [153.29233897564296, -27.8976119164061],
                  [153.29237339772322, -27.897575560605485],
                ],
              ],
            ],
          },
          geometry_name: 'geom',
          properties: {
            rec_id: 1598139,
            status: 'CURRENT',
            asset_numb: 'BOAR320',
            type: 'Boat Ramp',
            material: 'Gravel',
            number_lan: 1,
            add_improv: 'f',
            top_rl: 0,
            toe_rl: 0,
            area_: 36.079,
            comments: 'Council use only',
            documents: '../photos/31/j31p6.jpg',
            inspectors: null,
            inspection: '2009-09-23Z',
            constructi: null,
            record_cre: '2007-04-27Z',
            last_updat: null,
            update_dat: '2011-07-22Z',
            disposal_d: null,
            positional: 'GPS Corrected 1.0M',
            level_accu: null,
            owner: '251',
            project_nu: null,
            file_numbe: null,
            folder_num: null,
            drawing_nu: null,
            survey_num: null,
            condition: 4,
            historic_c: 0,
            funding_ba: 'Non GCCC',
            mi_symbolo: 'Pen (2, 2, 65535) Brush (1, 0, 16777215)',
            mi_prinx: 1598139,
            createuser: null,
            createdate: null,
            updateuser: null,
            updatedate: null,
            shape_leng: 25.1301720763,
            shape_area: 36.0791723381,
          },
        },
      ],
    };
    const map = { data: { addGeoJson: jest.fn() } };
    const google = { maps: { Map: jest.fn(() => map) } };
    window.google = google;
    document.getElementById = jest.fn().mockReturnValueOnce('el');
    const wrapper = shallow(<Map data={props}></Map>);
    const initMapSpy = jest.spyOn(wrapper.instance(), 'initMap');
    wrapper.setProps({ data: updatedProps });
    expect(initMapSpy).toBeCalledTimes(1);
    expect(document.getElementById).toBeCalledWith('map-js');
    expect(google.maps.Map).toBeCalledWith('el', {
      center: {
        lat: -27.9959656,
        lng: 153.2879044,
      },
      zoom: 9,
    });
    expect(map.data.addGeoJson).toBeCalledWith(updatedProps);
  });
});

单元测试结果:

 PASS  src/Whosebug/64635170/Map.test.js (10.908s)
  64635170
    ✓ should pass (9ms)

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