首页 > 解决方案 > 如何使用 jest 与 react 和 typescript 对 amcharts 进行单元测试?

问题描述

我已经重现了在使用 Jest 和 amCharts 进行项目时遇到的编译错误。显然,Jest 无法编译与 amchart 相关的任何内容以进行单元测试。

错误

/core.js:8
export { System, system } from "./.internal/core/System";
^^^^^^

SyntaxError: Unexpected token 'export'

  1 | import { useEffect, useRef } from "react";
> 2 | import * as am4core from "@amcharts/amcharts4/core";
    | ^
  3 | import * as am4charts from "@amcharts/amcharts4/charts";
  4 |
  5 | const data = [

  at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
  at Object.<anonymous> (src/App.tsx:2:1)

测试套件:1 个失败,总共 1 个测试:总共 0 个快照:总共 0 个时间:1.067 秒运行所有测试套件。

笑话.config.ts

module.exports = {
  roots: ["<rootDir>/src"],
  collectCoverageFrom: ["src/**/*.{js,jsx,ts,tsx}", "!src/**/*.d.ts"],
  setupFiles: ["react-app-polyfill/jsdom"],
  testMatch: [
    "<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
    "<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}",
  ],
  testEnvironment: "jsdom",
  testRunner:
    "/home/xeonrazr/Playground/amcharts-jest-err/node_modules/jest-circus/runner.js",
  transform: {
    "^.+\\.(js|jsx|mjs|cjs|ts|tsx)$": "<rootDir>/config/jest/babelTransform.js",
    "^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
    "^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)":
      "<rootDir>/config/jest/fileTransform.js",
  },
  transformIgnorePatterns: [
    "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$",
    "^.+\\.module\\.(css|sass|scss)$",
  ],
  modulePaths: [],
  moduleNameMapper: {
    "^react-native$": "react-native-web",
    "^.+\\.module\\.(css|sass|scss)$": "identity-obj-proxy",
  },
  moduleFileExtensions: [
    "web.js",
    "js",
    "web.ts",
    "ts",
    "web.tsx",
    "tsx",
    "json",
    "web.jsx",
    "jsx",
    "node",
  ],
  watchPlugins: [
    "jest-watch-typeahead/filename",
    "jest-watch-typeahead/testname",
  ],
  resetMocks: true,
};

应用程序.tsx

import { useEffect, useRef } from "react";
import * as am4core from "@amcharts/amcharts4/core";
import * as am4charts from "@amcharts/amcharts4/charts";

const data = [
  {
    country: "Lithuania",
    litres: 501.9,
  },
  {
    country: "Czech Republic",
    litres: 301.9,
  },
  {
    country: "Ireland",
    litres: 201.1,
  },
  {
    country: "Germany",
    litres: 165.8,
  },
  {
    country: "Australia",
    litres: 139.9,
  },
  {
    country: "Austria",
    litres: 128.3,
  },
  {
    country: "UK",
    litres: 99,
  },
  {
    country: "Belgium",
    litres: 60,
  },
  {
    country: "The Netherlands",
    litres: 50,
  },
];

function App() {
  const chartRef = useRef(am4core.create("chartdiv", am4charts.PieChart));

  useEffect(() => {
    let series = chartRef.current.series.push(new am4charts.PieSeries());
    series.dataFields.value = "litres";
    series.dataFields.category = "country";
    chartRef.current.data = data;
    chartRef.current.legend = new am4charts.Legend();
  }, []);

  return (
    <div className="App">
      <div
        data-testid="chartdiv"
        style={{ height: "600px", width: "100%" }}
        id="chartdiv"
      ></div>
    </div>
  );
}

export default App;


应用程序.test.tsx

import { render } from "@testing-library/react";
import App from "./App";

test("renders learn react link", () => {
  const { getByTestId } = render(<App />);
  const chartEl = getByTestId("chartdiv");
  expect(chartEl).toBeInTheDocument();
});

回购链接

标签: reactjstypescriptunit-testingjestjsamcharts

解决方案


Jest 目前不理解importexport。看起来您为您的 jest 配置遵循了 common setup docs,因此您可能正在使用 babel 并将您的代码从使用模块转换为使用 commonjs,但您没有转换您的依赖项:

transformIgnorePatterns: [
  "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$", // <-- do not transform node_modules
  "^.+\\.module\\.(css|sass|scss)$",
],

但是,导致您的问题的原因是您的其中一个导出 ( amCharts) 需要进行转换,以使这些import/export语句符合 jest 所期望的 commonjs 格式。

您最简单的解决方法可能是编辑transformIgnorePatterns

transformIgnorePatterns: [
    //Add other modules here that ship ESM that Jest doesn't like
    'node_modules/(?!@amcharts)',
    "^.+\\.module\\.(css|sass|scss)$",
  ],

所以我们说“继续,除非它匹配,否则不要转换节点模块中的任何内容@amcharts。如果您有更多需要转换的依赖项,那么您可以将其添加到该正则表达式中。

对于不同的解决方案,如果您喜欢实验性功能,那么您可以尝试打开 Jest 对 esm 的实验性支持:https ://jestjs.io/docs/ecmascript-modules 。


推荐阅读