
Jest 的 global setup/teardown 作用域隔离导致测试中对 global 对象的修改无法在 teardown 阶段访问;正确做法是将全局状态封装为可变对象(如配置对象),挂载到 global 上,再通过引用修改其属性。
jest 的 global setup/teardown 作用域隔离导致测试中对 `global` 对象的修改无法在 teardown 阶段访问;正确做法是将全局状态封装为可变对象(如配置对象),挂载到 `global` 上,再通过引用修改其属性。
在 Jest 中,global-setup.ts 和 global-teardown.ts 确实各执行一次,但 Jest 会在每个测试文件(甚至每个测试用例)运行前克隆或重置 global 对象的部分状态——尤其是直接挂载在 global 上的原始值(如 global.sometwo = 2)不会跨测试生命周期保留,因此 global-teardown 中读取不到测试中新增的顶层属性。
根本原因在于:Jest 的测试沙箱机制默认不保证 global 对象的跨测试可变性,直接赋值的原始类型字段(string、number、boolean)会被隔离,而对象引用则可被共享修改。
✅ 正确实践:将全局状态统一托管为一个可变对象(如 global.testConfig),所有动态字段均作为该对象的属性操作:
// testConfig.js
module.exports = {
someone: 1,
};
// global-setup.ts
const testConfig = require('./testConfig');
module.exports = async (config, projectConfig) => {
// 挂载整个配置对象(引用传递)
global.testConfig = testConfig;
};
// testfile.test.ts
describe('sometitle', () => {
test('testTitle', () => {
try {
console.log(global.testConfig.someone); // ✅ 输出 1
expect(false).toBe(true);
} catch (e) {
// ✅ 修改对象属性(非重新赋值 global.xxx)
global.testConfig.sometwo = 2;
throw e;
}
});
});
// global-teardown.ts
module.exports = async (globalConfig, projectConfig) => {
console.log(global.testConfig.someone); // ✅ 1
console.log(global.testConfig.sometwo); // ✅ 2 —— 此处可正常访问
};
⚠️ 注意事项:
- ❌ 避免 global.newField = value(原始值赋值),因其不可跨测试持久化;
- ✅ 始终通过 global.existingObject.newProp = value 方式扩展;
- 若需多测试间共享状态,建议额外结合 jest-worker 或临时文件,但应谨慎使用(影响测试隔离性);
- TypeScript 用户请为 global 添加类型声明(如 declare global { var testConfig: Record
; }),确保类型安全。
该方案兼顾 Jest 的设计约束与实际调试/状态跟踪需求,是符合测试最佳实践的稳健解法。











