问题有两个部分:
- testing
runSomeFunction()
- testing that the map handles click events correctly
对我来说,点击手是匿名功能:
(e) => {
const { lng, lat } = e.lngLat;
runSomeFunction(lat, lng);
}
<代码>runSomeFunction(>> 可与单位测试单独测试。
The click handler could possibly be tested in isolation with a unit test
if it s extracted to a named function.
The click handler can also be tested by firing a click event and
confirming that it calls a mocked runSomeFunction()
with the correct arguments, or confirming the end result of the click. I
would call these
integration tests instead of unit tests because they don t test the
click handler in isolation. I like this take on integration vs
unit
testing.
MapBox has resources on automated testing with real
browsers.
Jest
Here is a basic Map
jest mock to handle events with
mapbox-gl
3.1.2
.
测试环境是按最弱的docs子编成的bel子。
// tests/__mocks__/mapbox-gl.js
import EventEmitter from events ;
import { TextDecoder } from util ;
// Add `TextDecoder` to globals.
globalThis.TextDecoder = TextDecoder;
const mapboxActual = jest.requireActual( mapbox-gl );
/**
* Mock Map class.
*
* Extends the `EventEmitter` class and adds mock properties & methods.
*
* The real `Map` extends `Evented`, but `Evented.fire()` is now private
* and may be deprecated in the future.
*
* @see https://nodejs.org/api/events.html#class-eventemitter
* @see https://github.com/mapbox/mapbox-gl-js/blob/main/CHANGELOG.md#%EF%B8%8F-breaking-changes-5
*/
class MockMap extends EventEmitter {
// ... Put mock properties & methods here.
}
mapboxActual.Map = MockMap;
export default mapboxActual;
Using it
This is a trivial example that tests the runSomeFunction()
follow-through with a spy, only b/c I don t know a better way to confirm
that console.log()
was called correctly. In a real app, if
runSomeFunction()
renders something, you can test that it appears on
the screen as expected.
// runSomeFunction.js
export default function runSomeFunction(lat, lng) {
console.log(`Map clicked at ${lat}, ${lng}.`);
}
// map.js
import mapboxgl from mapbox-gl ;
import runSomeFunction from "./runSomeFunction";
// If you pull in `mapbox-gl` with an html `script` tag instead of
// importing it, you ll need to add `mapboxgl` to the globals for the
// test environment so that it s available here.
mapboxgl.accessToken = pk.eyJ1Ijoia2VudHIiLCJhIjoiY2tva3YxOWFzMDdpcDJvcno5ZjBzM3JvNCJ9.ZdH2WahCpmtdiLsNLWZNFQ ;
const map = new mapboxgl.Map({
container: map , // container ID
center: [ -74.5, 40 ], // starting position [lng, lat]
zoom: 9, // starting zoom
});
map.on( click , (e) => {
const { lng, lat } = e.lngLat;
runSomeFunction(lat, lng);
});
export default map;
// map.test.js
import map from ./map ;
jest.spyOn(console, log );
it( logs click on map , () => {
const testLatLng = {
lat: 39,
lng: -74,
};
// Confirm `console.log` not called before event is fired.
expect(console.log)
.not
.toBeCalled();
// Emit click event.
map.emit(
click ,
{
lngLat: testLatLng,
}
);
// Check result.
// May need delay for async event.
expect(console.log)
.toBeCalledTimes(1);
expect(console.log)
.toBeCalledWith(`Map clicked at ${testLatLng.lat}, ${testLatLng.lng}.`);
});
mapbox-gl
via script
tag
If you re pulling in mapbox-gl
via an html script
tag instead of
importing it into map.js
, here s an example of setting the global for
tests.
// jest.config.js
/** @type {import( jest ).Config} */
const config = {
setupFiles: [
<rootDir>/tests/setupTests.js
],
testEnvironment: "jsdom",
};
module.exports = config;
// tests/setupTests.js
import mapboxgl from "mapbox-gl";
globalThis.mapboxgl = mapboxgl;