用 jsodom 和 jest 测试 react-mapbox-gl
Posted
技术标签:
【中文标题】用 jsodom 和 jest 测试 react-mapbox-gl【英文标题】:Testing a react-mapbox-gl with jsodom and jest 【发布时间】:2018-07-29 16:24:17 【问题描述】:假设我们有以下 Map 组件。这是在 TypeScript 中,但同样适用于普通的 javascript。
import * as React from 'react';
import ReactMapboxGl from 'react-mapbox-gl';
const MapBox = ReactMapboxGl(
accessToken: 'pk.<redacted>'
);
export default class Map extends React.Component
render()
return (
<MapBox
style="mapbox://styles/mapbox/streets-v9"
zoom=[0]
containerStyle=
height: '500px',
width: 'inherit'
/>);
它是一些反应应用程序的一部分,被渲染成这样:
import * as React from 'react';
export default class App extends React.Component
render()
return (
<Map />
);
为了测试这个设置,我们使用 Jest 和 JSDOM。
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './App';
it('renders without crashing', () =>
const div = document.createElement('div');
ReactDOM.render(<App />, div);
);
此测试将无法运行并产生以下输出:
TypeError: window.URL.createObjectURL is not a function
at Object.254.../../source/worker (node_modules/mapbox-gl/dist/mapbox-gl.js:509:100)
at s (node_modules/mapbox-gl/dist/mapbox-gl.js:1:711)
at node_modules/mapbox-gl/dist/mapbox-gl.js:1:762
at Object.280.../ (node_modules/mapbox-gl/dist/mapbox-gl.js:561:28)
at s (node_modules/mapbox-gl/dist/mapbox-gl.js:1:711)
at node_modules/mapbox-gl/dist/mapbox-gl.js:1:762
at Object.263../worker_pool (node_modules/mapbox-gl/dist/mapbox-gl.js:527:29)
at s (node_modules/mapbox-gl/dist/mapbox-gl.js:1:711)
at node_modules/mapbox-gl/dist/mapbox-gl.js:1:762
at Object.191.../render/glyph_manager (node_modules/mapbox-gl/dist/mapbox-gl.js:383:809)
at s (node_modules/mapbox-gl/dist/mapbox-gl.js:1:711)
at node_modules/mapbox-gl/dist/mapbox-gl.js:1:762
at Object.248.../geo/lng_lat (node_modules/mapbox-gl/dist/mapbox-gl.js:497:338)
at s (node_modules/mapbox-gl/dist/mapbox-gl.js:1:711)
at node_modules/mapbox-gl/dist/mapbox-gl.js:1:762
at Object.72.../package.json (node_modules/mapbox-gl/dist/mapbox-gl.js:144:148)
at s (node_modules/mapbox-gl/dist/mapbox-gl.js:1:711)
at e (node_modules/mapbox-gl/dist/mapbox-gl.js:1:882)
at node_modules/mapbox-gl/dist/mapbox-gl.js:1:900
at Object.<anonymous>.i (node_modules/mapbox-gl/dist/mapbox-gl.js:1:177)
at Object.<anonymous> (node_modules/mapbox-gl/dist/mapbox-gl.js:1:413)
at Object.<anonymous> (node_modules/react-mapbox-gl/lib/map.js:21:16)
at Object.<anonymous> (node_modules/react-mapbox-gl/lib/index.js:3:13)
at Object.<anonymous> (src/Map.tsx:14:25)
at Object.<anonymous> (src/NewOrder.tsx:21:13)
at Object.<anonymous> (src/Routes.ts:17:18)
at Object.<anonymous> (src/App.tsx:16:16)
at Object.<anonymous> (src/App.test.tsx:6:169)
at <anonymous>
亲爱的读者,您的问题很简单:是否有可能解决这个问题?我们可以使用接缝来注入模拟的 MapBoxGL 库吗?
我在 GitHub 上发现了多个与此问题相关的问题,但没有一个提供解决方案:1、2。使用mapbox-gl-js-mock 的一些观点,而另一些则声称它没有用,因为它也需要真正的浏览器才能运行。
在 JSDOM 项目中还有 related issue 关于添加 URL.createObjectURL 可能会解决根本问题。
【问题讨论】:
【参考方案1】:如果您使用的是 import 和 typescript:
jest.mock('mapbox-gl/dist/mapbox-gl', () =>
return
'default':
accessToken: '',
GeolocateControl: jest.fn(),
Map: jest.fn(() => (
addControl: jest.fn(),
on: jest.fn(),
remove: jest.fn(),
fitBounds: jest.fn(),
)),
NavigationControl: jest.fn(),
);
【讨论】:
应该可以解决这个问题吗? github.com/visgl/react-map-gl/issues/1478【参考方案2】:您可以将此添加到setupTest.ts
的测试条目文件中
jest.mock('mapbox-gl/dist/mapbox-gl', () => (
GeolocateControl: jest.fn(),
Map: jest.fn(() => (
addControl: jest.fn(),
on: jest.fn(),
remove: jest.fn(),
)),
NavigationControl: jest.fn(),
));
【讨论】:
【参考方案3】:我遇到了同样的问题,当我将here 列出的以下代码添加到我的测试块的顶部时,它起作用了。
jest.mock('mapbox-gl/dist/mapbox-gl', () => (
Map: () => ()
));
【讨论】:
This issue 也是相关的。特别是,在我有一个工作设置之前,我必须走得更远(正如this comment 建议的那样)。以上是关于用 jsodom 和 jest 测试 react-mapbox-gl的主要内容,如果未能解决你的问题,请参考以下文章
用 Jest 和 Enzyme 测试 React Router
用 jest 和 react-testing-library 测试反应上下文