javascript测试中应通过beforeeach保存并替换全局构造函数、aftereach还原,或用jest.spyon自动管理;需用globalthis兼容多环境,避免顶层mock和箭头函数,esm中可借助object.defineproperty强制覆盖。

在 JavaScript 测试中,要替换全局构造函数(比如 Date、XMLHttpRequest、fetch 或自定义的全局类),核心思路是**临时覆盖全局对象上的属性**,并在测试结束后恢复原值,避免污染其他测试用例。
直接赋值覆盖 + beforeEach/afterEach 恢复
这是最常用、最可控的方式。适用于 Jest、Vitest 等主流测试框架:
- 在
beforeEach中保存原始构造函数,并用模拟实现替换 - 在
afterEach中还原,确保隔离性 - 注意:需使用
globalThis(或global,取决于环境)而非window,以兼容 Node 和浏览器环境
示例(Mock Date 始终返回固定时间):
let originalDate;
beforeEach(() => {
originalDate = globalThis.Date;
globalThis.Date = class extends Date {
constructor(...args) {
if (args.length === 0) {
super('2023-01-01T00:00:00Z');
} else {
super(...args);
}
}
};
});
afterEach(() => {
globalThis.Date = originalDate;
});
使用 Jest 的 spyOn + mockImplementation
Jest 提供了更安全的 API 来 mock 全局属性(包括构造函数),自动处理还原逻辑:
-
jest.spyOn(globalThis, 'Date').mockImplementation(...)是推荐做法 - 它会自动在每个测试后恢复,无需手动
afterEach - 注意:必须用
jest.spyOn而非直接赋值,否则 Jest 无法自动清理
示例:
beforeEach(() => {
jest.spyOn(globalThis, 'Date').mockImplementation(function (...args) {
if (args.length === 0) return new Date('2023-01-01T00:00:00Z');
return new Date(...args);
});
});
// 不需要 afterEach —— Jest 自动还原
Mock 自定义全局类(如 MyService)
如果类是挂载在全局(例如通过 globalThis.MyService = class {...} 暴露),同样适用上述方法:
- 用
jest.spyOn(globalThis, 'MyService')+mockImplementation - 或手动备份/替换,但需确保还原时机正确(尤其在异步测试中)
- 若类有静态方法,也可单独 mock:
MyService.doSomething = jest.fn()
示例(mock 全局 Logger 类):
const MockLogger = jest.fn().mockImplementation(() => ({
log: jest.fn(),
error: jest.fn()
}));
beforeEach(() => {
jest.spyOn(globalThis, 'Logger').mockImplementation(MockLogger);
});
test('uses mocked Logger', () => {
new globalThis.Logger();
expect(MockLogger).toHaveBeenCalledTimes(1);
});
注意事项与避坑点
以下细节容易导致 mock 失效或测试污染:
-
不要在模块顶层 mock:全局 mock 必须放在
beforeEach内,否则可能被其他测试提前执行 -
避免箭头函数作为构造函数:箭头函数不能用
new调用,mock 实现必须是普通函数或 class -
Node.js 环境下注意 global vs globalThis:Jest 默认使用
globalThis,但某些老版本需用global -
ESM 中全局变量不可写?:若测试运行在 ESM 模式且目标属性是只读(如某些内置构造函数),可用
Object.defineProperty强制覆盖(需配合writable: true)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











