Jest + @testing-library/react在来自[dom-accessibility-API]库的.mjs文件上抛出错误

9udxz4iz  于 2023-09-28  发布在  Jest
关注(0)|答案(3)|浏览(140)

我是第一次使用 Jest + @testing-library/react,在第一次尝试时,我在第三方库(可能是 react-testing-library 使用的)上得到了一个错误,我不知道如何修复。
这是我对ReactApp.js主组件的测试。基本上,我尝试用Redux商店 Package 它,然后验证DOM组件是否存在。很简单:

import React from 'react';
import '@testing-library/jest-dom/extend-expect';
import { render } from '@testing-library/react';
import { App } from '../../../src/features/root/App';
import { Provider } from "react-redux";
import { createStore } from "redux";
import { initialState } from '../../../src/features/root/redux/initialState';
import { reducer } from '../../../src/features/root/redux/reducer';

const renderWithProviders = (ui, { reduxState } = {}) => {
  const store = createStore(reducer, reduxState || initialState);
  return render(<Provider store={store}>{ui}</Provider>);
}

describe('root/App', () => {

  it('renders node with correct class name', () => {
    const { getByTestId } = renderWithProviders(<App />, { });
    const mainDiv = getByTestId('id-of-the-div');
    expect(mainDiv).toBeDefined();
  });
});

但是,在运行测试时,Jest会抛出以下错误:

Test suite failed to run

Jest encountered an unexpected token

This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

Here's what you can do:
 • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
 • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
 • If you need a custom transformation specify a "transform" option in your config.
 • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html

Details:

/sandbox/node_modules/dom-accessibility-api/dist/accessible-description.mjs:7
import { computeTextAlternative } from "./accessible-name-and-description.mjs";
^^^^^^

SyntaxError: Cannot use import statement outside a module

  at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
  at Object.<anonymous> (node_modules/dom-accessibility-api/sources/index.ts:1:1)

所以这里的关键点是:

/sandbox/node_modules/dom-accessibility-api/dist/accessible-description.mjs:7
import { computeTextAlternative } from "./accessible-name-and-description.mjs";
^^^^^^

SyntaxError: Cannot use import statement outside a module

看起来Jest无法解析该库dom-accessibility-API中的特定**.mjs文件。但为什么会这样呢?在任何使用react-testing-library和Jest**进行React测试的教程中,似乎都没有提到这一点。这是一个我不知道的第三方图书馆。
有人知道如何解决这个问题吗?我的主要配置文件:

babel.config.js

const presets = [    
  'react-app'    
];

module.exports = { presets };

jest.config.js:(我尝试了许多选项和简化,但都无济于事)

module.exports = {
reporters: [
    "default",
    "jest-junit"
  ],
  coverageReporters: [
    "lcov",
    "text",
    "cobertura"
  ],
  collectCoverageFrom: [
    "src/**/*.{js,jsx}"
  ],
  setupFiles: [        
    "<rootDir>/tests/setup.js",
    "jest-localstorage-mock",
    "jest-canvas-mock"
  ],
  snapshotSerializers: [
    "enzyme-to-json/serializer"
  ],
  testMatch: [
    "<rootDir>/tests/**/*.test.js"
  ],
  testEnvironment: "jsdom",
  testURL: "http://localhost",
  transform: {
    "^.+\\.(js|jsx)$": "babel-jest",
    "^.+\\.(ts|tsx|mjs)$": "ts-jest",
    "^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
    "^(?!.*\\.(js|jsx|mjs|css|json|ts)$)": "<rootDir>/config/jest/fileTransform.js"
  },
  transformIgnorePatterns: [
    "[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|ts|tsx)$"
  ],
  testPathIgnorePatterns: ["<rootDir>/build/", "<rootDir>/node_modules/"],
  moduleNameMapper: {
    "^react-native$": "react-native-web"
  },
  moduleFileExtensions: [
    "web.js",
    "mjs",
    "js",
    "ts",
    "json",
    "web.jsx",
    "jsx",
    "node"
  ]  
}

/tests/setup.js:(仅用于初始化其他类型测试的Enzyme)

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter(), disableLifecycleMethods: true });

/config/jest/fileTransform.js

'use strict';

const path = require('path');

// This is a custom Jest transformer turning file imports into filenames.
// http://facebook.github.io/jest/docs/en/webpack.html

module.exports = {
  process(src, filename) {
    return `module.exports = ${JSON.stringify(path.basename(filename))};`;
  },
};

package.json:(仅显示devDependencies)

"devDependencies": {
 "@babel/core": "^7.12.10",
 "@babel/preset-env": "^7.12.11",
 "@babel/preset-react": "^7.12.10",
 "@babel/preset-typescript": "^7.12.7",
 "@testing-library/jest-dom": "^5.11.9",
 "@testing-library/react": "^11.2.3",
 "axios-mock-adapter": "^1.15.0",
 "babel-eslint": "^10.1.0",
 "babel-jest": "^26.6.3",
 "babel-loader": "^8.2.2",
 "babel-preset-react-app": "^10.0.0",
 "babel-runtime": "^6.26.0",
 "browser-refresh-taglib": "^1",
 "case-sensitive-paths-webpack-plugin": "2.1.1",
 "cross-env": "^5.2.0",
 "enzyme": "^3.11.0",
 "enzyme-adapter-react-16": "^1.15.5",
 "enzyme-to-json": "^3.6.1",
 "eslint": "^7.17.0",
 "eslint-config-react-app": "^6.0.0",
 "eslint-loader": "^4.0.2",
 "eslint-plugin-flowtype": "^5.2.0",
 "eslint-plugin-import": "^2.22.1",
 "eslint-plugin-jsx-a11y": "^6.4.1",
 "eslint-plugin-react": "^7.22.0",
 "eslint-plugin-react-hooks": "^4.2.0",
 "extract-text-webpack-plugin": "3.0.2",
 "html-webpack-plugin": "2.29.0",
 "jest": "^26.6.3",
 "jest-canvas-mock": "^2.2.0",
 "jest-junit": "^5.2.0",
 "jest-localstorage-mock": "^2.3.0",
 "jest-when": "^2.7.0",
 "nock": "^9.2.3",
 "optimizer-plugin-inc": "^4",
 "query-string": "5.1.1",
 "react-dev-utils": "^5.0.0",
 "redux-mock-store": "^1.5.4",
 "redux-thunk": "^2.3.0",
 "sw-precache-webpack-plugin": "0.11.4",
 "ts-jest": "^26.4.4",
 "webpack": "3.8.1",
 "webpack-bundle-analyzer": "^3.0.3",
 "webpack-dev-server": "2.9.4",
 "webpack-hot-middleware": "^2.22.2",
 "webpack-manifest-plugin": "1.3.2"
};
tcbh2hod

tcbh2hod1#

看来我找到解决办法了。基于该示例:react-redux
我更新并简化了我的jest.config.js如下:

const path = require('path')

module.exports = {

    roots: [path.resolve(__dirname, './tests')],

    reporters: [
        "default",
        "jest-junit"
    ],
    coverageReporters: [
      "lcov",
      "text",
      "cobertura"
    ],
    collectCoverageFrom: [
      "src/**/*.{js,jsx}"
    ],
    setupFiles: [        
      path.resolve(__dirname, "./tests/setup.js"),
      "jest-localstorage-mock",
      "jest-canvas-mock"
    ],
  
    setupFilesAfterEnv: [path.resolve(__dirname, './tests/setupAfterEnv.js')],

    testMatch: [
      "**/tests/**/*.test.js"
    ],
  
    testURL: "http://localhost"
}

并添加了一个setupAfterEnv.js文件,其中只有这一行:

import '@testing-library/jest-dom/extend-expect'

到目前为止,测试可以通过了...
老实说,我仍然不知道为什么以前我得到这个错误,我不认为变化是实质性的...

ifmq2ha2

ifmq2ha22#

看起来真实的的解决方法是删除/禁用代码转换。
以下是Jest 27.4文档(当前版本):https://jestjs.io/docs/ecmascript-modules,#1:确保您通过传递transform: {}来禁用代码转换,或者配置您的Transformer以发出ESM而不是默认的CommonJS(CJS)。
这正是您在jest.config.js文件中所做的。
希望这有助于更好地理解这个问题!

0pizxfdo

0pizxfdo3#

jest.config.js中的moduleFileExtensions具体如下:

// jest.config.js
module.exports = {
  // ...
  moduleFileExtensions: ["js", "jsx", "ts", "tsx", "json"]
  // ...
}

Jest docs:moduleFileExtensions

相关问题