React-Leaflet:'Invalid LatLng object' on 运行 test when using boundsOptions
React-Leaflet: 'Invalid LatLng object' on running test when using boundsOptions
我使用 react-leaflet 构建了一个简单的应用程序来显示地图。该应用程序本身正在运行,并且地图在浏览器中正确显示。但是,当我尝试使用 react-testing-library 编写测试时,在使用 boundsOptions
时,我在执行中收到 Invalid LatLng object
'。如果我删除 boundsOptions 属性 测试将通过。
Map.tsx
import "leaflet/dist/leaflet.css";
import React from "react";
import {
LayersControl,
Marker,
Polyline,
TileLayer,
Tooltip,
Map
} from "react-leaflet";
import './Map.css';
const { BaseLayer } = LayersControl;
const MapWrapper: React.FC = ({ ...props }) => {
const layers = [
{
name: "OpenStreetMap.Mapnik",
attribution:
'© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
}
];
const bounds: [number, number][] = [];
[...] // Code that calculates the bounds to show (in production)
if (bounds.length === 0) {
bounds.push([35, -35]);
bounds.push([65, 55]);
}
return (
<Map bounds={bounds} boundsOptions={{ padding: [5, 5] }} className="map">
<LayersControl position="topright">
{layers.map(layer => {
return (
<BaseLayer
key={layer.url}
checked={true}
name={layer.name}
>
<TileLayer attribution={layer.attribution} url={layer.url} />
</BaseLayer>
);
})}
</LayersControl>
</Map>
);
};
Map.css
.map {
height: 400px;
width: 640px;
}
Map.test.tsx
import React from 'react'
import MapWrapper from './Map';
import {render, fireEvent, cleanup} from '@testing-library/react';
afterEach(cleanup)
test('Simple test', () => {
const { getByTestId } = render(<MapWrapper />)
})
测试出错
console.error node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/virtual-console.js:29
Error: Uncaught [Error: Invalid LatLng object: (NaN, NaN)]
at reportException (C:\Repos\react-leaflet-jest\node_modules\jest-environment-jsdom\node_modules\jsdom\lib\jsdom\living\helpers\runtime-script-errors.js:66:24)
...
console.error node_modules/react-dom/cjs/react-dom.development.js:19814
The above error occurred in the <TileLayer> component:
in TileLayer (created by Context.Consumer)
您可以在这里找到代码:https://bitbucket.org/netcoding/react-leaflet-jest/src/master/
如何使用 boundsOptions 设置 react-leaflet 以通过测试?
它似乎是 known issue 并且也可以复制,例如在 Jest 中。出现异常是因为渲染地图时(在测试中)无法正确确定地图容器大小。
解决方案是明确设置地图容器大小,如果react-leaflet
library地图容器大小可以这样设置:
const { leafletElement: map } = this.mapRef.current as Map;
const container = map.getContainer(); //get leaflet map container
Object.defineProperty(container, "clientWidth", { value: 800 });
Object.defineProperty(container, "clientHeight", { value: 600 });
这是一个关于如何测试地图边界的完整示例:
test("Map test bounds", () => {
class TestComponent extends React.Component<any, any> {
mapRef: React.RefObject<Map>;
constructor(props: any) {
super(props);
this.mapRef = React.createRef();
}
componentDidMount() {
this.updateBoundsOptions();
}
resizeContainer(container: HTMLElement) {
Object.defineProperty(container, "clientWidth", { value: 800 });
Object.defineProperty(container, "clientHeight", { value: 600 });
}
updateBoundsOptions() {
const { leafletElement: map } = this.mapRef.current as Map;
const container = map.getContainer(); //get leaflet map container
this.resizeContainer(container);
map.fitBounds(this.props.bounds, this.props.boundsOptions);
}
render() {
return (
<MapWrapper mapRef={this.mapRef}>
<span />
</MapWrapper>
);
}
}
render(
<TestComponent
bounds={[[35, -35], [65, 55]]}
boundsOptions={{ padding: [5, 5] }}
/>
);
});
其中 MapWrapper
是自定义组件:
export interface MapWrapperProps extends MapProps {
mapRef?: React.RefObject<Map>;
}
const MapWrapper: React.FC<MapWrapperProps> = ({ ...mapProps }) => {
return (
<Map ref={mapProps.mapRef} {...mapProps}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
</Map>
);
};
我使用 react-leaflet 构建了一个简单的应用程序来显示地图。该应用程序本身正在运行,并且地图在浏览器中正确显示。但是,当我尝试使用 react-testing-library 编写测试时,在使用 boundsOptions
时,我在执行中收到 Invalid LatLng object
'。如果我删除 boundsOptions 属性 测试将通过。
Map.tsx
import "leaflet/dist/leaflet.css";
import React from "react";
import {
LayersControl,
Marker,
Polyline,
TileLayer,
Tooltip,
Map
} from "react-leaflet";
import './Map.css';
const { BaseLayer } = LayersControl;
const MapWrapper: React.FC = ({ ...props }) => {
const layers = [
{
name: "OpenStreetMap.Mapnik",
attribution:
'© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
}
];
const bounds: [number, number][] = [];
[...] // Code that calculates the bounds to show (in production)
if (bounds.length === 0) {
bounds.push([35, -35]);
bounds.push([65, 55]);
}
return (
<Map bounds={bounds} boundsOptions={{ padding: [5, 5] }} className="map">
<LayersControl position="topright">
{layers.map(layer => {
return (
<BaseLayer
key={layer.url}
checked={true}
name={layer.name}
>
<TileLayer attribution={layer.attribution} url={layer.url} />
</BaseLayer>
);
})}
</LayersControl>
</Map>
);
};
Map.css
.map {
height: 400px;
width: 640px;
}
Map.test.tsx
import React from 'react'
import MapWrapper from './Map';
import {render, fireEvent, cleanup} from '@testing-library/react';
afterEach(cleanup)
test('Simple test', () => {
const { getByTestId } = render(<MapWrapper />)
})
测试出错
console.error node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/virtual-console.js:29
Error: Uncaught [Error: Invalid LatLng object: (NaN, NaN)]
at reportException (C:\Repos\react-leaflet-jest\node_modules\jest-environment-jsdom\node_modules\jsdom\lib\jsdom\living\helpers\runtime-script-errors.js:66:24)
...
console.error node_modules/react-dom/cjs/react-dom.development.js:19814
The above error occurred in the <TileLayer> component:
in TileLayer (created by Context.Consumer)
您可以在这里找到代码:https://bitbucket.org/netcoding/react-leaflet-jest/src/master/
如何使用 boundsOptions 设置 react-leaflet 以通过测试?
它似乎是 known issue 并且也可以复制,例如在 Jest 中。出现异常是因为渲染地图时(在测试中)无法正确确定地图容器大小。
解决方案是明确设置地图容器大小,如果react-leaflet
library地图容器大小可以这样设置:
const { leafletElement: map } = this.mapRef.current as Map;
const container = map.getContainer(); //get leaflet map container
Object.defineProperty(container, "clientWidth", { value: 800 });
Object.defineProperty(container, "clientHeight", { value: 600 });
这是一个关于如何测试地图边界的完整示例:
test("Map test bounds", () => {
class TestComponent extends React.Component<any, any> {
mapRef: React.RefObject<Map>;
constructor(props: any) {
super(props);
this.mapRef = React.createRef();
}
componentDidMount() {
this.updateBoundsOptions();
}
resizeContainer(container: HTMLElement) {
Object.defineProperty(container, "clientWidth", { value: 800 });
Object.defineProperty(container, "clientHeight", { value: 600 });
}
updateBoundsOptions() {
const { leafletElement: map } = this.mapRef.current as Map;
const container = map.getContainer(); //get leaflet map container
this.resizeContainer(container);
map.fitBounds(this.props.bounds, this.props.boundsOptions);
}
render() {
return (
<MapWrapper mapRef={this.mapRef}>
<span />
</MapWrapper>
);
}
}
render(
<TestComponent
bounds={[[35, -35], [65, 55]]}
boundsOptions={{ padding: [5, 5] }}
/>
);
});
其中 MapWrapper
是自定义组件:
export interface MapWrapperProps extends MapProps {
mapRef?: React.RefObject<Map>;
}
const MapWrapper: React.FC<MapWrapperProps> = ({ ...mapProps }) => {
return (
<Map ref={mapProps.mapRef} {...mapProps}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
/>
</Map>
);
};