我正在尝试通过 React 和 Babel 让我的第一个 Jest 测试通过。
我收到以下错误:
语法错误:/Users/manueldupont/test/avid-sibelius-publishing-viewer/src/components/TransportButton/TransportButton.less:意外令牌
> 7 | @import '../variables.css';
| ^
我开玩笑的 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"
]
},
那么我错过了什么?
moduleNameMapper
是告诉 Jest 如何解释具有不同扩展名的文件的设置。你需要告诉它如何处理 Less 文件。
在您的项目中创建一个这样的文件(如果您愿意,可以使用不同的名称或路径):
配置/CSSStub.js
module.exports = {};
这个存根是我们将告诉 Jest 使用而不是 CSS 或 Less 文件的模块。然后更改 moduleNameMapper
设置并将此行添加到其对象以使用它:
'^.+\\.(css|less)$': '<rootDir>/config/CSSStub.js'
现在 Jest 会将任何 CSS 或 Less 文件视为导出空对象的模块。你也可以做其他事情——例如,如果你使用 CSS 模块,你可以使用代理,这样每次导入都会返回导入的属性名称。
阅读此 guide 了解更多信息。
我通过在 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 模块,那么最好模拟代理以启用类名查找。因此您的配置将更改为:
{
"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
moduleNameMapper
不是受支持的覆盖。评论时的版本是 1.1.4。
更新从 2018 年 2 月开始使用 create-react-app 的更新。您不能覆盖 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
类似的情况,安装 identity-object-proxy 并将其添加到我的 CSS 笑话配置中对我有用。
//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';
@import Unexpected token=的解决方法=:)
安装包:
npm i --save-dev identity-obj-proxy
添加 jest.config.js
module.exports = {
"moduleNameMapper": {
"\\.(css|less|scss)$": "identity-obj-proxy"
}
}
如果您使用 ts-jest,上述解决方案均无效!您需要模拟转换。
jest.config.js
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'
},
};
文件-mock.js
module.exports = {
process() {
return `module.exports = 'test-file-stub'`;
},
};
样式-mock.js
module.exports = {
process() {
return 'module.exports = {};';
}
};
如果您想了解更多详细信息,我发现此方法有效example。
declare module '*.scss';
或类似内容的 types.d.ts 文件。
更新:2021 年 8 月如果您使用带有 TypeScript 的 Next JS。只需按照示例回购。
否则,您将浪费时间配置环境。
https://github.com/vercel/next.js/blob/canary/examples/with-typescript-eslint-jest/package.json
我在 package.json 的底部添加了 moduleNameMapper,我在其中配置了我的玩笑,就像这样:
"jest": {
"verbose": true,
"moduleNameMapper": {
"\\.(scss|less)$": "<rootDir>/config/CSSStub.js"
}
}
moduleNameMappers
中有以下键值对:"\\.(css|sass)$": "identity-obj-proxy"
,但是,我有一些.sass
文件使用@import
关键字,使 transformAndBuildScript 函数抛出。有没有什么办法解决这一问题?\\.sass$
文件的空对象的sassMock.js
文件,我也会看到相同的错误。"\\.(css|less)$": "identity-obj-proxy"
对我有用