项目描述:
基于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
原因
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
原因
Jsdom不支持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.
`
原因
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的时候避坑,特此总结