ReferenceError:在使用 jest 和 msw v2.0 测试运行期间未定义 TextEncoder

Nas*_*ova 8 node.js reactjs jestjs msw

我有一个正在运行的 React 应用程序,我用它msw来在浏览器和测试中模拟 BE(开玩笑)。使用 msw v1.3.0 一切都工作得很好,我决定更新它 v2.0,但我遇到了问题。由于错误,我所有的测试都失败了ReferenceError: TextEncoder is not defined。在浏览器模式下它工作正常。

我已联系msw支持人员,他们告诉我这个问题与 Jest 有关。我已经尝试了很多解决方法,如何TextEncoder在通常情况下定义可能起作用的地方,但都是徒劳的。

ps所有版本都是新的(node:v18.14.2,npm:v9.5.0,typescript:v4.9.5,react:v18.2.0,jest:v27.5.1)。我运行我的测试craco test


我尝试创建一个单独的jest.config.js文件并TextEncoder如下定义:

module.exports = {
  globals: {
     TextEncoder: require('util').TextEncoder,
     TextDecoder: require('util').TextDecoder,
  }
}
Run Code Online (Sandbox Code Playgroud)

并从文件中:

module.exports = {
  setupFiles: ['<rootDir>/setupFiles.js'],
}

Run Code Online (Sandbox Code Playgroud)

我尝试从 'util' 和 'node:util' 导入 TextEncoder:

const { TextDecoder, TextEncoder } = require('node:util');

Object.defineProperties(globalThis, {
  TextDecoder: { value: TextDecoder, writable: true },
  TextEncoder: { value: TextEncoder, writable: true },
});
Run Code Online (Sandbox Code Playgroud)

我尝试从不同的外部“文本编码”库导入它。并添加 testEnvironment: 'node'配置。但所有这些都不适用于我的情况。

Sha*_*son 4

我怀疑这些“环境”库在内部使用 VM 另一个库来创建沙箱。JSDOM 及其竞争对手 HappyDOM 的全局变量中都没有 TextDecoder / TextEncoder 的实现,因此不仅找不到它们,而且如果无法访问虚拟机内的全局上下文,也无法添加它们。

他们这样做的原因是他们模拟浏览器,如果“fs”或其他节点标准库可访问,那就没有意义了。

试试这个,让我知道它是否有效;在带有 MSW 2.0 的 Node 18.18.2 上为我工作

// inside your jest.setup.js
testEnvironment: "./jest.environment.js",
Run Code Online (Sandbox Code Playgroud)
// test.environment.js

const Environment = require("jest-environment-jsdom").default;

module.exports = class CustomTestEnvironment extends Environment {
    async setup() {
        await super.setup();
        this.global.TextEncoder = TextEncoder;
        this.global.TextDecoder = TextDecoder;
        this.global.Response = Response;
        this.global.Request = Request;
        
    }
};
Run Code Online (Sandbox Code Playgroud)

我认为这个解决方案是部分破解,但除了创建 PR 或使用 JSDOM 或 HappyDOM 问题来添加对这些的支持之外,您的选择非常有限。