Jest 的 global-setup/teardown 仅共享初始化后的全局对象快照,测试中直接赋值 global.xxx 不会持久化到 teardown 阶段;正确做法是将全局状态封装为可变对象(如 global.testConfig),通过引用修改实现跨生命周期数据共享。
jest 的 global-setup/teardown 仅共享初始化后的全局对象快照,测试中直接赋值 `global.xxx` 不会持久化到 teardown 阶段;正确做法是将全局状态封装为可变对象(如 `global.testconfig`),通过引用修改实现跨生命周期数据共享。
在 Jest 中,global-setup.ts 和 global-teardown.ts 确实各自只执行一次,但它们运行在不同的 Node.js 进程上下文中(尤其启用 --runInBand 以外的并行模式时),且 Jest 会对 global 对象做隔离处理——这意味着测试文件中对 global 的直接属性赋值(如 global.sometwo = 2)不会反映到 teardown 进程的 global 对象上,导致 global.sometwo 在 teardown 中为 undefined。
根本原因在于:Jest 并未将测试进程中的 global 变更同步回 setup/teardown 进程;global 在各进程间是独立副本,而非共享引用。
✅ 正确解决方案:将配置状态封装为一个挂载在 global 上的可变对象,而非直接添加顶层属性。这样,所有进程都操作同一引用(前提是该对象在 setup 中已创建并挂载):
定义可变配置对象(例如 testConfig.js):
// testConfig.jsmodule.exports = {someone: 1,};
在 global-setup 中挂载该对象到 global:
// global-setup.tsconst testConfig = require('./testConfig');
module.exports = async (config, projectConfig) => {// 挂载为全局可变容器(注意:必须是引用类型!)global.testConfig = testConfig;};
3. **测试中通过该容器读写状态**:```ts// testfile.test.tsdescribe('sometitle', () => { test('testTitle', () => { try { console.log(global.testConfig.someone); // 输出: 1 expect(false).toBe(true); } catch (e) { // ✅ 修改的是 testConfig 对象的属性,而非 global 本身 global.testConfig.sometwo = 2; throw e; } });});
// global-teardown.tsmodule.exports = async (globalConfig, projectConfig) => {console.log(global.testConfig.someone); // 1console.log(global.testConfig.sometwo); // 2 ✅ 正确输出};
⚠️ 注意事项:
总结:不要直接向 global 添加临时字段,而应将其作为“命名空间容器”,统一管理可变配置——这是 Jest 环境下安全、可靠、符合最佳实践的全局状态共享方式。