You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js配置jest-fetch-mock运行测试报TextEncoder未定义错误

问题原因

之前尝试从util引入TextEncoder挂载全局不生效,核心原因是挂载时机过晚:setupFilesAfterEnv里的脚本会在Jest测试框架、Next.js测试配置加载完成后才执行,而Next.js内部模块、jsdom环境初始化阶段就已经调用了TextEncoder,此时全局还没有注入对应API,就会抛出引用错误。

可行解决方案

方案1:提前注入全局polyfill(优先使用,适配90%以上场景)

  1. 在项目根目录新建jest.polyfills.js文件,写入以下内容:
/* eslint-disable @typescript-eslint/no-var-requires */
const { TextEncoder, TextDecoder } = require('util')

// 同时挂载到全局对象,覆盖Node环境与jsdom window上下文
Object.assign(globalThis, {
  TextEncoder,
  TextDecoder,
  // 若后续抛出Request/Response/Headers未定义错误,可保留以下配置(Node 18+ 内置支持)
  Request,
  Response,
  Headers
})
  1. 修改jest.config.js中的配置,将polyfill加入setupFiles数组(该配置下的脚本执行时机早于setupFilesAfterEnv,会在测试环境初始化前完成注入):
const customJestConfig = {
  // 新增该行,polyfill必须放在最前
  setupFiles: ['<rootDir>/jest.polyfills.js'],
  setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
  moduleDirectories: ['<rootDir>/node_modules', '<rootDir>/src', '<rootDir>/pages'],
  testEnvironment: 'jest-environment-jsdom',
  testPathIgnorePatterns: [
    '<rootDir>/.next/',
    '<rootDir>/node_modules/',
    '<rootDir>/coverage',
    '<rootDir>/dist'
  ],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/$1'
  },
  resolver: '<rootDir>/.jest/resolver.js'
}

方案2:自定义jsdom测试环境(方案1无效时使用)

如果方案1仍报错,说明jsdom环境实例化阶段就需要调用TextEncoder,此时通过自定义测试环境在构造阶段注入API即可:

  1. 在项目根目录新建jest.environment.js文件,写入以下内容:
/* eslint-disable @typescript-eslint/no-var-requires */
const JsdomEnvironment = require('jest-environment-jsdom')
const { TextEncoder, TextDecoder } = require('util')

module.exports = class CustomTestEnvironment extends JsdomEnvironment {
  constructor(config, context) {
    super(config, context)
    // 环境实例化阶段直接挂载API到jsdom全局上下文
    this.global.TextEncoder = TextEncoder
    this.global.TextDecoder = TextDecoder
    this.global.Request = Request
    this.global.Response = Response
    this.global.Headers = Headers
  }
}
  1. 修改jest.config.js中的testEnvironment配置,指向自定义环境文件:
const customJestConfig = {
  setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
  // 替换原有testEnvironment配置
  testEnvironment: '<rootDir>/jest.environment.js',
  // 其余配置保持不变
  moduleDirectories: ['<rootDir>/node_modules', '<rootDir>/src', '<rootDir>/pages'],
  testPathIgnorePatterns: [
    '<rootDir>/.next/',
    '<rootDir>/node_modules/',
    '<rootDir>/coverage',
    '<rootDir>/dist'
  ],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/$1'
  },
  resolver: '<rootDir>/.jest/resolver.js'
}

兼容处理

如果你的Node.js版本低于18,从util引入的API可能存在兼容问题,可以安装text-encoding包做polyfill,将上述代码中引入util的部分替换为:

const { TextEncoder, TextDecoder } = require('text-encoding')

注意不要在jest.setup.ts中重复覆盖TextEncoder、TextDecoder全局变量,避免产生冲突。

内容的提问来源于stack exchange,提问作者rottitime

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 10:36:16