我正在努力让我的第一次Jest测试通过React和Babel。
我收到以下错误:
SyntaxError:/Users/manueldupont/test/avid-sibelius-publishing-viewer/src/components/TransportButton/TransportButton.less:意外的令牌
> 7 | @import '../variables.css';
| ^
我对于jest的package.json配置如下所示:
"babel": {
"presets": [
"es2015",
"react"
],
"plugins": [
"syntax-class-properties",
"transform-class-properties"
]
},
"jest": {
"moduleNameMapper": {
"^image![a-zA-Z0-9$_-]+$": "GlobalImageStub",
"^[./a-zA-Z0-9$_-]+\\.png$": "RelativeImageStub"
},
"testPathIgnorePatterns": [
"/node_modules/"
],
"collectCoverage": true,
"verbose": true,
"modulePathIgnorePatterns": [
"rpmbuild"
],
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react/",
"<rootDir>/node_modules/react-dom/",
"<rootDir>/node_modules/react-addons-test-utils/",
"<rootDir>/node_modules/fbjs",
"<rootDir>/node_modules/core-js"
]
},
那么我错过了什么?
答案 0 :(得分:47)
moduleNameMapper
是告诉Jest如何解释具有不同扩展名的文件的设置。你需要告诉它如何处理Less文件。
在项目中创建这样的文件(如果您愿意,可以使用其他名称或路径):
config/CSSStub.js
module.exports = {};
这个存根是我们告诉Jest使用的模块,而不是CSS或Less文件。然后更改moduleNameMapper
设置并将此行添加到其对象以使用它:
'^.+\\.(css|less)$': '<rootDir>/config/CSSStub.js'
现在,Jest会将任何CSS或Less文件视为导出空对象的模块。您也可以执行其他操作 - 例如,如果使用CSS模块,则可以使用代理,以便每次导入都返回导入的属性名称。
阅读本指南中的更多内容:https://facebook.github.io/jest/docs/en/webpack.html
答案 1 :(得分:12)
我通过在package.json文件中的jest配置中使用moduleNameMapper
键解决了这个问题
{
"jest":{
"moduleNameMapper":{
"\\.(css|less|sass|scss)$": "<rootDir>/__mocks__/styleMock.js",
"\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
}
}
}
在此之后,您需要创建如下所述的两个文件
__mocks__/styleMock.js
module.exports = {};
__mocks__/fileMock.js
module.exports ='test-file-stub';
如果您使用的是CSS模块,那么最好模拟代理以启用className查找。 因此,您的配置将更改为:
{
"jest":{
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|less|scss|sass)$": "identity-obj-proxy"
},
}
}
但是你需要安装identity-obj-proxy
包作为开发依赖,即。
yarn add identity-obj-proxy -D
了解更多信息。您可以参考jest docs
答案 2 :(得分:1)
UPDATE。 您不能在package.json中覆盖moduleNameMapper,但是在jest.config.js中它可以工作,但是不幸的是,我没有找到有关此功能的任何文档。 所以我的 jest.config.js 看起来像这样:
module.exports = {
...,
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(scss|sass|css)$": "identity-obj-proxy"
}
}
它很好地跳过了scss文件和@import。
支持我的回答,我跟随jest webpack
答案 3 :(得分:1)
如果您使用的是ts-jest,则上述任何解决方案都将无法使用!您需要模拟转换。
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
roots: [
"<rootDir>/src"
],
transform: {
".(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/jest-config/file-mock.js",
'.(css|less)$': '<rootDir>/jest-config/style-mock.js'
},
};
module.exports = {
process() {
return `module.exports = 'test-file-stub'`;
},
};
module.exports = {
process() {
return 'module.exports = {};';
}
};
我发现此功能有效example
答案 4 :(得分:0)
类似的情况,安装identity-object-proxy并将其添加到CSS的Jest配置中对我来说很有效。
//jest.config.js
module.exports = {
moduleNameMapper: {
"\\.(css|sass)$": "identity-obj-proxy",
},
};
我看到的具体错误:
Jest encountered an unexpected token
/Users/foo/projects/crepl/components/atoms/button/styles.css:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){.button { }
^
SyntaxError: Unexpected token .
1 | import React from 'react';
> 2 | import styles from './styles.css';
答案 5 :(得分:0)
我在package.json的底部添加了moduleNameMapper,在其中我配置了笑话,就像这样:
"jest": {
"verbose": true,
"moduleNameMapper": {
"\\.(scss|less)$": "<rootDir>/config/CSSStub.js"
}
}
答案 6 :(得分:0)
更新:2021 年 8 月 如果您使用带有 TypeScript 的 Next JS。只需按照示例存储库操作即可。
否则您将浪费时间配置环境。
https://github.com/vercel/next.js/blob/canary/examples/with-typescript-eslint-jest/package.json