问题分析与修复
错误原因 Jest 28调整了测试环境模块的导出格式,jest-environment-node不再直接导出NodeEnvironment构造函数,而是导出一个包含该构造函数的包装对象。你之前的代码直接require('jest-environment-node')拿到的是这个对象,而非可继承的构造函数,因此继承时会抛出“Class extends value # is not a constructor or null”的错误。
修复方法 修改jest.env.js的导入逻辑,正确获取NodeEnvironment构造函数即可:
方案1:解构导入 const { NodeEnvironment } = require('jest-environment-node');
module.exports = class CustomTestEnvironment extends NodeEnvironment {
async setup() {
await super.setup();
if (typeof this.global.TextEncoder === 'undefined') {
const { TextEncoder } = require('util');
this.global.TextEncoder = TextEncoder;
}
if (typeof this.global.TextDecoder === 'undefined') {
const { TextDecoder } = require('util');
this.global.TextDecoder = TextDecoder;
}
}
};
方案2:通过.default获取默认导出 如果解构方式不生效,可尝试直接取默认导出:
const NodeEnvironment = require('jest-environment-node').default;
module.exports = class CustomTestEnvironment extends NodeEnvironment {
async setup() {
await super.setup();
if (typeof this.global.TextEncoder === 'undefined') {
const { TextEncoder } = require('util');
this.global.TextEncoder = TextEncoder;
}
if (typeof this.global.TextDecoder === 'undefined') {
const { TextDecoder } = require('util');
this.global.TextDecoder = TextDecoder;
}
}
};
替代方案 如果不想维护自定义测试环境,也可以通过全局初始化脚本实现相同效果:
创建setup-jest.js文件: const { TextEncoder, TextDecoder } = require('util');
global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;
在jest.config.js中配置: module.exports = {
// 其他配置项...
setupFilesAfterEnv: ['./setup-jest.js'],
};
内容的提问来源于stack exchange,提问作者user3142695