在Jest测试中使用webpack的worker-loader解析导入

时间:2017-03-02 22:53:22

标签: webpack loader jestjs worker

我正在写一个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')
        }
      },

4 个答案:

答案 0 :(得分:3)

如果不需要解析路径,则可以使用"moduleNameMapper"忽略导入。

首先,创建一个包含export default ''的空模块。

接下来,将以下内容添加到您的package.json中:

"jest": {
    "moduleNameMapper": {
        "^worker-plugin/loader.+$": "<rootDir>/EmptyModule"
    }
}

答案 1 :(得分:1)

根据cpojer,Jest不支持网络工作者。您应该使用嘲笑,阅读更多here

答案 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"
}