在Jest测试中使用webpack的worker-loader解决导入问题 [英] Resolving imports using webpack's worker-loader in Jest tests

查看:572
本文介绍了在Jest测试中使用webpack的worker-loader解决导入问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个Jest测试,无法解决使用webpack的worker-loader

I'm writing a Jest test and am having trouble resolving this import which uses webpack's worker-loader

import ImageInfoWorker from 'worker-loader?name=image_info!@WORKERS/image-info';

我还有一些其他别名可以在测试中正确解析,例如:

I have some other aliases which are resolving properly in my tests, such as:

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部分:

And here is the resolve section of my webpack config:

        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')
        }
      },

推荐答案

此方法对我适用于内联样式和配置样式的工作程序导入.

This approach worked for me with both inline-style and config-style worker imports.

捆绑了Webpack的WebWorkers尚未被Jest支持(我不知道),因此您必须嘲笑该worker.只需将worker的功能提取到外部文件,然后在worker文件中仅执行worker-y位即可.

Webpack-bundled WebWorkers are not suported by Jest yet (not that I know of), so you have to mock the worker. Simply extract the functionality of your worker to an external file, and in the worker file perform just the worker-y bits.

@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部分:

This way you can mock just the Worker part of your implementation, while testing the actual functionality:

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文件,第二个路径用于我们要测试的实际功能.以下内容也可以工作:

Note I didn't include the inline worker-loader config, but I skipped the ^(.*). This works because we don't need worker-loader anymore since we are mocking the worker. The first path is for .worker.js files that we want to mock and the other is for actual functionality that we want to test. The following would also work:

    "^(.*?)@WORKERS/(.*\\.worker\\.js)$": "<rootDir>/mocks/$2",
    "^(.*?)@WORKERS/(.*)$": "<rootDir>/js/workers/$2",

此解决方案可能可以推广,以便所有工作人员都可以被嘲笑,欢迎提出建议.

This solution could probably be generalized so that all workers are mocked at once, suggestions welcome.

这篇关于在Jest测试中使用webpack的worker-loader解决导入问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆