如何在Jest测试中使用我的webpack的html-loader导入?

Jan*_*nis 8 import ecmascript-6 jestjs babeljs webpack-html-loader

我刚刚开始使用Jest测试框架,虽然直接单元测试工作正常,但我在测试其模块中的任何组件(通过babel + webpack的ES模块)需要HTML文件时遇到大量问题.

这是一个例子:

import './errorHandler.scss';
import template from './errorHandler.tmpl';

class ErrorHandler {
    ...
Run Code Online (Sandbox Code Playgroud)

我正在加载我在Jest的package.json配置中设置的组件特定SCSS文件以返回一个空对象但是当Jest尝试运行该import template from './errorHandler.tmpl';行时它会断开说:

/Users/jannis/Sites/my-app/src/scripts/errorHandler/errorHandler.tmpl.html:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){<div class="overlay--top">
                                                                                         ^
    SyntaxError: Unexpected token <

        at transformAndBuildScript (node_modules/jest-runtime/build/transform.js:284:10)
Run Code Online (Sandbox Code Playgroud)

我的Jest配置package.json如下:

"jest": {
    "setupTestFrameworkScriptFile": "<rootDir>/test/setupFile.js",
    "moduleDirectories": ["node_modules"],
    "moduleFileExtensions": ["js", "json", "html", "scss"],
    "moduleNameMapper": {
        "^.+\\.scss$": "<rootDir>/test/styleMock.js"
    }
}
Run Code Online (Sandbox Code Playgroud)

似乎webpack html-loader与Jest无法正常工作,但我找不到任何有关如何解决此问题的解决方案.

有谁知道如何html-loader import在我的测试中使这些工作?他们加载我的lodash模板标记,我宁愿不在我的.js文件中有这些大量的HTML块,所以我可以省略该import template from x部分.

PS:这不是一个反应项目,只是简单的webpack,babel,es6.

bnj*_*rsn 14

我最近遇到了这个特定的问题,创建自己的转换preprocesser将解决它.这是我的设置:

的package.json

"jest": {
    "moduleFileExtensions": [
      "js",
      "html"
    ],
    "transform": {
      "^.+\\.js$": "babel-jest",
      "^.+\\.html$": "<rootDir>/test/utils/htmlLoader.js"
    }
 }
Run Code Online (Sandbox Code Playgroud)

注意:默认情况下通常包含babel-jest,但如果指定自定义转换预处理器,则似乎必须手动包含它.

测试/ utils的/ htmlLoader.js:

const htmlLoader = require('html-loader');

module.exports = {
    process(src, filename, config, options) {
        return htmlLoader(src);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 当我尝试这样做时,我收到错误:“转换的‘process’函数必须返回一个字符串,或者一个包含此字符串的‘code’键的对象。”。这是否可能只适用于旧版本的 jest 或 html-loader? (3认同)
  • @SamHasler是的,“html-loader”变成了异步函数,使用“html-loader-jest”。它的功能基本相同,但需要带有同步接口的旧“html-loader”版本。 (2认同)

Sam*_*uru 9

聚会有点晚了,但想补充一点,如果你想走那条路,还有这个html-loader-jest npm 包可以做到这一点。

一旦你 npm install 它,你将把它添加到你的 jest 配置中

"transform": {
        "^.+\\.js$": "babel-jest",
        "^.+\\.html?$": "html-loader-jest"
    }
Run Code Online (Sandbox Code Playgroud)


小智 5

对于Jest > 28.xxhtml-loader

  1. 创建一个自定义转换器,如此处所述
jest/html-loader.js
Run Code Online (Sandbox Code Playgroud)
const htmlLoader = require("html-loader");

module.exports = {
  process(sourceText) {
    return {
      code: `module.exports = ${htmlLoader(sourceText)};`,
    };
  },
};
Run Code Online (Sandbox Code Playgroud)
  1. 将其添加到您的笑话配置中。
jest.config.js
Run Code Online (Sandbox Code Playgroud)
jest.config.js
Run Code Online (Sandbox Code Playgroud)

它将修复错误:返回值无效:process()或/和processAsync()在“<PATH>”找到的代码转换器的方法应返回一个对象或解析为对象的 Promise。

  • 我尝试了这个并开始收到错误 `({"Object.&lt;anonymous&gt;":function(module,exports,require,__dirname,__filename,jest){module.exports = [object Promise]; ^^^^^^^ SyntaxError :意外的标识符` (2认同)
  • @abhishekhandait 哦,那是因为您使用的 html-loader 版本肯定是最新的,因此它返回的是 Promise 而不是值。它不兼容。html-loader-jest 曾经通过依赖旧版本的 html-loader 来解决这个问题。但它不适用于 Jest 28+ 我创建了 https://www.npmjs.com/package/jest-html-loader 来完成 Jest 28+ 的工作 (2认同)

rob*_*i24 0

也许您自己的预处理器文件将是解决方案:

脚本预处理器

自定义预处理器

scriptpreprocessor:从预处理源文件提供同步功能的模块的路径。例如,如果您希望能够在模块或测试中使用节点尚不支持的新语言功能(例如 ES6 类),您可以插入将 ES6 编译为ES5在这里。

当我在添加到 webpack 模块加载器后遇到测试问题时,我创建了自己的预处理器transform-decorators-legacy