如何在Jest中模拟global.window为undefined测试Node分支逻辑
解决Jest测试Node环境分支:将window设为undefined的正确姿势
我之前也踩过这个坑!默认情况下,如果你的Jest测试环境启用了jsdom(比如Create React App或者配置了testEnvironment: 'jsdom'),window对象会被自动注入,导致没法触发Node.js分支的逻辑。下面给你两种可靠的解决方法:
先看示例函数(方便对照)
假设你的通用函数长这样:
// your-function.js export function myUniversalFn() { if (typeof window !== 'undefined') { // 浏览器环境逻辑 return 2; } else { // Node.js环境逻辑 return 1; } }
方法1:临时删除/恢复global.window
这种方法简单直接,适合单个测试用例:
// your-function.test.js import { myUniversalFn } from './your-function'; test('返回1(Node.js环境,window不存在)', () => { // 先保存原始window,避免污染其他测试 const originalWindow = global.window; // 删除global上的window属性(注意不是赋值undefined,有些环境中window是不可写的) delete global.window; // 验证返回值 expect(myUniversalFn()).toBe(1); // 测试结束后恢复window,保证其他测试不受影响 global.window = originalWindow; });
方法2:用Jest Spy修改window的getter
如果直接删除window不生效(比如jsdom的window是通过getter定义的),可以用jest.spyOn来mock getter:
test('返回1(通过mock window getter模拟Node环境)', () => { // mock global.window的getter,让它返回undefined const windowSpy = jest.spyOn(global, 'window', 'get').mockImplementation(() => undefined); expect(myUniversalFn()).toBe(1); // 恢复mock,避免影响后续测试 windowSpy.mockRestore(); });
常见坑点说明
- 为什么直接赋值
global.window = undefined可能没用?
有些测试环境(比如jsdom)中,window是不可配置的属性,直接赋值不会改变它的存在性。用delete或者mock getter才能真正让typeof window返回'undefined'。 - TypeScript用户注意
如果用TS,需要给global加类型断言:(global as any).window,因为TS默认的NodeJS.Global类型不包含window属性。
完整测试示例
import { myUniversalFn } from './your-function'; describe('myUniversalFn 环境兼容性测试', () => { test('Node.js环境下返回1', () => { const originalWindow = global.window; delete global.window; expect(myUniversalFn()).toBe(1); global.window = originalWindow; }); test('浏览器环境下返回2', () => { // 确保window存在(如果测试环境默认有这步可省略) global.window = {}; expect(myUniversalFn()).toBe(2); }); });
内容的提问来源于stack exchange,提问作者Daniel Billingham
相关产品推荐
相关产品推荐

