如何使用 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
我对 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