怎么测试react-app带ant-design/charts

1,458 阅读2分钟

react-scripts很好用,做react-app很简单。ant-design也是很好,我最喜欢@ant-design/charts做GUI。

但它们混在一起的时候有个问题,npm testyarn test都不能用!我们来一个一个解决吧~

SyntaxError: Unexpected token 'export'

第一个问题是这样:

/home/runner/work/jest-with-antd/jest-with-antd/node_modules/lodash-es/lodash.js:10
export { default as add } from './add.js';
^^^^^^

SyntaxError: Unexpected token 'export'

lodash-es 是个ES Module,所以Jest要转换。但react-scripts的默认配置下,Jest不进行转换node_modules目录下的文件。@antv/xflow-coreantd也有这个问题,所以我们需要package.json里加个配置:

  "jest": {
    "moduleNameMapper": {
      "\\.(css|less)$": "identity-obj-proxy"
    },
    "transformIgnorePatterns": [
      "node_modules/(?!(@antv/xflow-core/es|antd/es|lodash-es)/)"
    ]
  }

TypeError: window.URL.createObjectURL is not a function

第二个是jsdom的问题。jsdom还没提供URL.createObjectURL函数, 所以mapbox-gl不能工作:

TypeError: window.URL.createObjectURL is not a function
  1 | import React from 'react';
> 2 | import { Line } from '@ant-design/charts';
    | ^
  3 |
  4 | const App: React.FC = () => {
  5 |   const data = [
  at define (node_modules/mapbox-gl/dist/mapbox-gl.js:25:41)

所以我们来mock一下:

diff --git a/src/setupTests.js b/src/setupTests.js
index 8f2609b..95a1adb 100644
--- a/src/setupTests.js
+++ b/src/setupTests.js
@@ -3,3 +3,4 @@
 // expect(element).toHaveTextContent(/react/i)
 // learn more: https://github.com/testing-library/jest-dom
 import '@testing-library/jest-dom';
+URL.createObjectURL = jest.fn();

需要的话,可以用beforeEach()重置模拟:

diff --git a/src/setupTests.js b/src/setupTests.js
index 8f2609b..95a1adb 100644
--- a/src/setupTests.js
+++ b/src/setupTests.js
@@ -3,3 +3,7 @@
 // expect(element).toHaveTextContent(/react/i)
 // learn more: https://github.com/testing-library/jest-dom
 import '@testing-library/jest-dom';
+const mockFn = URL.createObjectURL = jest.fn();
+beforeEach(() => {
+  mockFn.mockClear();
+});

TypeError: Cannot read properties of null (reading 'save')

第三也是TypeError,但它自来@antv/g-base

TypeError: Cannot read properties of null (reading 'save')

  3 |
  4 | test('renders learn react link', () => {
> 5 |   render(<App />);
    |   ^
  6 |   const linkElement = screen.getByText(/Export Image/i);
  7 |   expect(linkElement).toBeInTheDocument();
  8 | });

我们还可以看别的一个错误:

Error: Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)

它说我们要安装canvas软件包,所以我们来npm add -D canvas就行。

Attempted import error: '__spreadArray' is not exported from 'tslib'

你可能看见第四个错误,它说tslib不提供__spreadArray函数。

Attempted import error: '__spreadArray' is not exported from 'tslib'.

你用v2.1.0版本就可以解决这问题,所以我们加个resolutionspackage.json里吧:

  "resolutions": {
    "tslib": ">=2.1.0"
  }

总结

结束了!一个一个错误看起来有点复杂,但不太魔法。希望这篇文章对你的日常工作有所帮助。 GitHub上我做的有样品项目,你来加个星🌟吧~