我使用webpack来开发一个React组件 . 这是一个简单的版本:
'use strict';
require('./MyComponent.less');
var React = require('react');
var MyComponent = React.createClass({
render() {
return (
<div className="my-component">
Hello World
</div>
);
}
});
module.exports = MyComponent;
现在,我想使用jest来测试这个组件 . 这是我的 package.json
的相关位:
"scripts": {
"test": "jest"
},
"jest": {
"rootDir": ".",
"testDirectoryName": "tests",
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
"unmockedModulePathPatterns": [
"react"
]
}
运行 npm test
时,出现以下错误:
SyntaxError:/Users/mishamoroshko/react-component/src/tests/MyComponent.js:/Users/mishamoroshko/react-component/src/MyComponent.js:/Users/mishamoroshko/react-component/src/MyComponent.less:意外的令牌ILLEGAL
看起来webpack需要在jest运行测试之前处理 require('./MyComponent.less')
.
我想知道我是否需要使用像jest-webpack这样的东西 . 如果是,有没有办法指定多个 scriptPreprocessor
? (注意我已经使用 babel-jest
)
11 回答
我们在CSS文件中遇到了类似的问题 . 正如你之前提到的jest-webpack解决了这个问题 . 您也不必模拟或使用任何模块映射器 . 对于我们来说,我们将npm测试命令从
jest
替换为jest-webpack
,它刚刚起作用 .Webpack是一个很棒的工具,但我不喜欢我的Jest单元测试,并且在运行单元测试之前添加webpack构建只会减慢这个过程 . 教科书的答案是使用
"moduleNameMapper"
选项模拟非代码依赖项https://facebook.github.io/jest/docs/webpack.html#handling-static-assets
我发现忽略所需模块的最干净的解决方案是使用moduleNameMapper config(适用于最新版本0.9.2)
文档很难遵循 . 我希望以下内容有所帮助 .
将moduleNameMapper键添加到packages.json配置中 . 项的键应该是所需字符串的正则表达式 . '.less'文件示例:
将EmptyModule.js添加到根文件夹:
注释很重要,因为moduleNameMapper使用EmptyModule作为此模块的别名(read more about providesModule) .
现在每个需要与正则表达式匹配的引用将被替换为空字符串 .
如果您将moduleFileExtensions配置与'js'文件一起使用,那么请确保您还将EmptyModule添加到'unmockedModulePathPatterns' .
这是我最终得到的最佳配置:
我最终得到了以下黑客攻击:
但是,我仍然想知道这个问题的正确解决方案是什么 .
我刚发现它's even simpler with Jest' s
moduleNameMapper
配置 .Jest的更多细节tutorial page .
我最近发布了Jestpack,这可能有所帮助 . 它首先使用Webpack构建您的测试文件,因此任何自定义模块解析/加载器/插件等都可以工作,您最终会使用JavaScript . 然后,它为Jest提供了一个自定义模块加载器,它可以理解Webpack模块运行时 .
来自Jest docs:
上面的代码段将所有
.less
文件路由到新的依赖项identity-obj-proxy
,它将在调用时返回带有类名的字符串,例如:'styleName'
forstyles.styleName
.我认为一个不太常见的解决方案是将预处理器包装在与javascript文件匹配的文件名中:
即使您没有在require行中显式设置扩展名并且不需要在源上进行正则表达式替换,这也可以工作 .
我遇到过类似的问题
见https://github.com/kriasoft/react-starter-kit/blob/9204f2661ebee15dcb0b2feed4ae1d2137a8d213/src/components/ContactPage/ContactPage.js#L4-L7的例子
为了运行Jest,我有两个问题:
导入
.css
申请装饰
@withStyles
(TypeError: <...> (0 , _appDecoratorsWithStyles2.default)(...) is not a function
)First one 是通过在脚本预处理器中模拟
.css
本身来解决的 .通过使用
unmockedModulePathPatterns
从自动锁定中排除装饰器来解决 Second one示例基于https://github.com/babel/babel-jest/blob/77a24a71ae2291af64f51a237b2a9146fa38b136/index.js
另请注意:使用jest预处理器时,应清除缓存:
从Misha的回应中汲取灵感,我创建了一个NPM包来解决这个问题,同时还处理了我遇到的一些场景:
webpack-babel-jest
希望这可以节省下一个人几个小时 .
如果你正在使用babel,你可以使用类似https://github.com/Shyp/babel-plugin-import-noop之类的东西在babel变换期间删除不需要的导入,并配置你的
.babelrc
test
env来使用插件,如下所示: