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

Posted

技术标签:

【中文标题】如何在 Jest 测试中使用我的 webpack 的 html-loader 导入?【英文标题】:How can I use my webpack's html-loader imports in Jest tests? 【发布时间】:2017-01-21 20:57:42 【问题描述】:

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

这是一个例子:

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

class ErrorHandler 
    ...

我正在加载我在 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)

package.json 我的 Jest 配置如下:

"jest": 
    "setupTestFrameworkScriptFile": "<rootDir>/test/setupFile.js",
    "moduleDirectories": ["node_modules"],
    "moduleFileExtensions": ["js", "json", "html", "scss"],
    "moduleNameMapper": 
        "^.+\\.scss$": "<rootDir>/test/styleMock.js"
    

似乎 webpack html-loader 无法与 Jest 一起正常工作,但我找不到任何解决方案。

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

PS:这不是一个 react 项目,只是普通的 webpack、babel、es6。

【问题讨论】:

【参考方案1】:

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

package.json

"jest": 
    "moduleFileExtensions": [
      "js",
      "html"
    ],
    "transform": 
      "^.+\\.js$": "babel-jest",
      "^.+\\.html$": "<rootDir>/test/utils/htmlLoader.js"
    
 

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

test/utils/htmlLoader.js:

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

module.exports = 
    process(src, filename, config, options) 
        return htmlLoader(src);
    

【讨论】:

这很有帮助,谢谢。我还想补充一点,您也可以使用 underscore-template-loader 来执行此操作。 当我尝试这个时,我得到错误:“转换的process 函数必须返回一个字符串,或者带有包含此字符串的code 键的对象。”。这是否可能仅适用于旧版本的 jest 或 html-loader? @SamHasler 是的,“html-loader”变成了异步函数,使用“html-loader-jest”。它的功能基本相同,但需要带有同步接口的旧“html-loader”版本。【参考方案2】:

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

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

"transform": 
        "^.+\\.js$": "babel-jest",
        "^.+\\.html?$": "html-loader-jest"
    

【讨论】:

感谢您,您让我免于数小时的调查!突然将moduleNameMapper 用于html 模块导致Jest 无法导入fake-indexeddb,不知道为什么。【参考方案3】:

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

ScriptPreprocessor

Custom-preprocessors

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

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

【讨论】:

【参考方案4】:

html-loader-jest 不适合我。我的解决方法:

"transform": 
  '\\.(html)$': '<rootDir>/htmlTemplateMock.html'

htmlTemplateMock.html 是空文件

【讨论】:

以上是关于如何在 Jest 测试中使用我的 webpack 的 html-loader 导入?的主要内容,如果未能解决你的问题,请参考以下文章

在 Jest 测试中使用 Webpack 的 DefinePlugin 变量

如何在 React 和 Webpack 中使用 Jest

使用 webpack-hot-middleware 配置环境时,Jest 测试失败

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

使用 Jest 和 Webpack 别名进行测试

使用 webpack 配置运行 Jest 测试