I built an simple app using react-leaflet to show a map. The app itself is working and the map is showing correctly in the browser. But when I try to write tests with react-testing-library, I receive Invalid LatLng object
' in execution when using boundsOptions
. If I remove the boundsOptions property the test will pass.
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 />)
})
Error occurred by test
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)
You can find the code here: https://bitbucket.org/netcoding/react-leaflet-jest/src/master/
How can I setup react-leaflet to pass the test using the boundsOptions?
It appears to be a known issue and also could be reproduced, for example in Jest. The exception occurs since map container size could not be properly determined when map is rendered (in tests).
The solution would be to explicitly set map container size , in case of react-leaflet
library map container size could be set like this:
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 });
Here is a complete example on how to test map bounds:
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] }}
/>
);
});
where MapWrapper
is a custom component:
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>
);
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.