You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React项目Jest测试出现ReferenceError: window is not defined问题求助

解决Jest测试中FirebaseUI抛出"window is not defined"的问题

我来帮你梳理下这个问题:虽然你的测试代码完全没碰FirebaseUI,但你依赖的@piccollage/cbjs模块里的firebaseAuth.js文件已经引入了FirebaseUI——而FirebaseUI在初始化阶段就会直接访问浏览器的window对象。Jest默认运行在Node.js环境下,没有原生的window对象,所以哪怕你没调用相关代码,只要模块被加载就会触发这个错误。

下面给你几个针对性的解决方案,按需选择:

方案一:给Jest提供浏览器环境(最简单直接)

把Jest的测试环境从node改成jsdom,它会模拟完整的浏览器DOM环境,包括window对象。修改你的jest.config.js:

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'jsdom', // 把这里从node改成jsdom
  transformIgnorePatterns: [
    'node_modules/(?!(cbjs)/)',
  ],
  transform: { "^.+\\.(ts|js|jsx)$": "ts-jest" },
  moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
};

这个方案的好处是一劳永逸,不需要额外模拟单个对象,适合大部分需要浏览器环境的测试场景。如果你的其他测试确实需要Node.js环境,也可以给单个测试文件单独指定环境,比如在测试文件顶部加:

/**
 * @jest-environment node
 */

方案二:提前模拟window对象

如果你不想切换到jsdom环境,可以在测试的前置文件(也就是你导入的setup_test)里提前给全局对象添加window模拟。修改cbjs/setup_test:

// 先模拟window对象,再导入其他依赖
global.window = {};
// 如果FirebaseUI还需要document或者其他浏览器API,可以补充模拟
global.window.document = {
  createElement: () => ({})
};

// 原来的setup_test代码放在后面

这样当FirebaseUI模块被加载时,就能找到它需要的window对象了。

方案三:Mock掉FirebaseUI或依赖它的模块

如果你想更精准地隔离依赖,可以用Jest的mock功能直接替换掉FirebaseUI,或者替换掉引入它的firebaseAuth.js模块。

比如在你的测试文件顶部添加:

// Mock掉FirebaseUI模块,返回一个空的模拟对象
jest.mock('firebaseui', () => ({
  AuthUI: jest.fn(),
  // 如果你知道项目里用到了FirebaseUI的其他导出,也可以在这里补充模拟
}));

// 或者直接mock掉引入FirebaseUI的firebaseAuth.js模块
jest.mock('@piccollage/cbjs/dist/src/firebaseAuth.js', () => ({
  // 导出该模块原本需要提供的内容,比如如果有初始化函数,就模拟一个空函数
  initAuth: jest.fn()
}));

这个方案适合你只想隔离特定依赖,不想改变整体测试环境的场景。

最后提醒下:如果你的setup_test里有导入其他依赖的代码,一定要确保模拟window或者mock模块的代码放在所有导入之前,这样才能在模块加载前完成模拟。

内容的提问来源于stack exchange,提问作者Jasper Huang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 08:12:30