Dumi+Ts+Jest+Antd踩坑实录

1,980 阅读2分钟

项目描述:

基于antd进行二次封装的公司组件库,单元测试的技术栈:jest+enzyme

成果(公司项目,不便开源,见谅):

jest配置文件jest.config.js

module.exports = {
  // 测试用例运行在一个类似于浏览器的环境里,可以调用浏览器的 API
  testEnvironment: 'jest-environment-jsdom-fourteen',
  roots: ['<rootDir>'],
  setupFiles: ['<rootDir>/scripts/setup.jest.ts'],
  transform: {
    '\.(ts|tsx)$': 'ts-jest',
    '\.(js|jsx)$': 'babel-jest',
  },
  testRegex: '(/__tests__/.*|(\.|/)(test|spec))\.tsx?$',
  moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
  snapshotSerializers: ['enzyme-to-json/serializer'],
  moduleDirectories: ['node_modules'],
  transformIgnorePatterns: ['<rootDir>/node_modules/(?!antd)'],
  moduleNameMapper: {
    '\.(css|less)$': 'identity-obj-proxy',
    'antd/es': '<rootDir>/node_modules/antd/dist/antd.min.js',
  },
};

setup.ts文件

import { configure } from 'enzyme';
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';

Object.defineProperty(window, 'matchMedia', {
  writable: true,
  value: jest.fn().mockImplementation((query) => ({
    matches: false,
    media: query,
    onchange: null,
    addListener: jest.fn(), // deprecated
    removeListener: jest.fn(), // deprecated
    addEventListener: jest.fn(),
    removeEventListener: jest.fn(),
    dispatchEvent: jest.fn(),
  })),
});

configure({ adapter: new Adapter() });

踩坑记录

1.react版本过高

表现

TypeError: Cannot read property 'child' of undefined

image.png 原因

react版本为17版本,jest官方暂时没有对react17进行支持

解决办法

安装  @wojtekmaj/enzyme-adapter-react-17 类库

2.react与react-dom版本不一致

由于该问题需要安装依赖进行复现,所以这里就不截图展示了,见谅

表现

Invalid Hook Call Warning

解决办法

统一react与react-dom的版本
因为我们是ts项目,所以我们这里需要修改的是@types/react和@types/react-dom的版本
写着篇文章的时候@types/react的最新版本是17.0.39;
@types/react-dom的最新版本是17.0.11;
只要两者不跨大版本即可运行!!!

3.使用jsdom创建浏览器环境。但是JSDom不支持window.matchMedia

表现

TypeError: window.matchMedia is not a function

image.png 原因

Jsdom不支持window.matchMedia

解决办法

手动模拟window.matchMedia,详见官方例子:

手动模拟window.matchMedia

4.jest无法翻译解析es模块

表现 ` 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.

` image.png 原因

jest的翻译器无法解析es模块的代码,网上查阅解决办法说bable可以解决,但是我用这个方法没解决,大家可以试试看

路径:解决jest处理es模块

解决办法

手动指定无法解析模块需要使用的js文件
eg:我是antd/es模块报错,所以我就在jest配置文件的 
moduleNameMapper 模块的映射文件路径
antd/es': '<rootDir>/node_modules/antd/dist/antd.min.js

官方文档:jest配置映射配置

总结

遇到问题多查,多翻看官方文档,最后不得不说一句,StackOverflow yyds!!!

希望这篇文章可以帮大家在玩儿jest的时候避坑,特此总结