我正在写一个Jest测试,并且无法解决使用webpack worker-loader
import ImageInfoWorker from 'worker-loader?name=image_info!@WORKERS/image-info';
我有一些其他别名可以在我的测试中正确解析,例如:
import Store from '@SUPPORT/store';
import * as api from '@SUPPORT/api';
以下是package.json
"jest": {
"moduleFileExtensions": ["js", "jsx"],
"moduleNameMapper": {
"^@CSS/(.*)$": "<rootDir>/css/$1",
"^@COMPONENTS/(.*)$": "<rootDir>/js/components/$1",
"^@MODELS/(.*)$": "<rootDir>/js/models/$1",
"^@STORES/(.*)$": "<rootDir>/js/stores/$1",
"^@SUPPORT/(.*)$": "<rootDir>/js/support/$1",
"^(.*?)@WORKERS/(.*)$": "$1<rootDir>/js/workers/$2"
}
}
这是我的webpack配置的resolve
部分:
resolve: {
extensions: ['.js', '.jsx'],
modules: [process.env.NODE_PATH, 'node_modules'],
alias: {
'@CSS': path.join(projectRoot, 'css'),
'@COMPONENTS': path.join(projectRoot, 'js', 'components'),
'@MODELS': path.join(projectRoot, 'js', 'models'),
'@STORES': path.join(projectRoot, 'js', 'stores'),
'@SUPPORT': path.join(projectRoot, 'js', 'support'),
'@WORKERS': path.join(projectRoot, 'js', 'workers')
}
},
答案 0 :(得分:3)
如果不需要解析路径,则可以使用"moduleNameMapper"
忽略导入。
首先,创建一个包含export default ''
的空模块。
接下来,将以下内容添加到您的package.json
中:
"jest": {
"moduleNameMapper": {
"^worker-plugin/loader.+$": "<rootDir>/EmptyModule"
}
}
答案 1 :(得分:1)
答案 2 :(得分:0)
这种方法对内联样式导入和配置样式导入都有效。
捆绑了Webpack的WebWorkers尚未被Jest支持(我不知道),因此您必须嘲笑该worker。只需将worker的功能提取到外部文件,然后在worker文件中仅执行worker-y位即可。
@WORKERS/imageInfo.js
-工作人员的“肉”:
export default imageInfoFunction(data) {
//...
}
@WORKERS/imageInfo.worker.js
,工人的肉汁:
import imageInfoFunction from "./imageInfo";
self.onmessage = async function (e) {
self.postMessage(imageInfoFunction(e.data));
};
通过这种方法,您可以在测试实际功能的同时仅模拟实现的Worker部分:
mocks/imageInfo.worker.js
import imageInfoFunction from "@WORKERS/imageInfo";
export default class ImageInfoWorker {
constructor() {
// should be overwritten by the code using the worker
this.onmessage = () => { };
}
// mock expects data: { } instead of e: { data: { } }
postMessage(data) {
// actual worker implementation wraps argument into { data: arg },
// so the mock needs to fake it
this.onmessage({ data: imageInfoFunction (data) });
}
}
现在在jest.config.js
中:
module.exports = {
moduleNameMapper: {
"@WORKERS/(.*\\.worker\\.js)$": "<rootDir>/mocks/$1",
"@WORKERS/(.*)$": "<rootDir>/js/workers/$1",
},
};
请注意,我没有包含内联worker-loader
配置,但是我跳过了^(.*)
。之所以可行,是因为我们在嘲笑该工作程序后不再需要worker-loader
。第一个路径用于我们要模拟的.worker.js文件,另一个路径用于我们要测试的实际功能。以下方法也可以:
"^(.*?)@WORKERS/(.*\\.worker\\.js)$": "<rootDir>/mocks/$2",
"^(.*?)@WORKERS/(.*)$": "<rootDir>/js/workers/$2",
此解决方案可能可以推广,以便所有工作人员都可以被嘲笑,欢迎提出建议。
答案 3 :(得分:0)
这 solution 对我有用。
在名为 __mocks__
的文件夹中创建一个带有模拟实现的 workerMock.js 文件(当然你可以在任何你喜欢的地方创建它):
module.exports = Object.create(null);
然后在您的 jest 配置中添加以下配置:
"moduleNameMapper": {
"\\.worker.js":"<rootDir>/__mocks__/workerMock.js"
}