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

React集成Firebase认证Jest测试报ERR_UNHANDLED_REJECTION怎么解决

错误原因

  • 你添加的try/catch仅包裹了onAuthStateChanged监听方法的注册逻辑,该方法本身是同步执行的,不会抛出异步错误。本次报错来自Firebase初始化、认证模块异步加载、StyledFirebaseAuth组件内部发起的异步请求,这些异步逻辑的异常不在当前try/catch的捕获范围内。
  • 测试环境默认不会加载项目的.env环境变量,同时Jest的jsdom运行环境默认禁止真实网络请求,Firebase在测试环境中无法完成初始化和接口调用,才会抛出未处理的Promise拒绝。

排查步骤

  1. 先打印未处理Promise的具体报错信息,在Jest的全局setup文件(通常为src/setupTests.js)中添加如下代码,即可看到具体的拒绝原因:
process.on('unhandledRejection', (reason, promise) => {
  console.error('未处理的Promise拒绝,位置:', promise, '原因:', reason);
});

解决方案

单元测试不应该调用真实的第三方服务接口,你需要Mock所有Firebase相关依赖,步骤如下:

  1. 在测试文件顶部添加Firebase模块的Mock逻辑,模拟认证相关的所有方法和属性:
// Mock 整个firebase模块
jest.mock('firebase', () => {
  const mockAuthInstance = {
    onAuthStateChanged: jest.fn((callback) => {
      // 测试登录按钮场景,默认返回未登录状态
      callback(null);
      return jest.fn(); // 返回取消监听的方法
    }),
    signOut: jest.fn().mockResolvedValue(),
    currentUser: null,
    GoogleAuthProvider: { PROVIDER_ID: 'google.com' },
    FacebookAuthProvider: { PROVIDER_ID: 'facebook.com' },
    TwitterAuthProvider: { PROVIDER_ID: 'twitter.com' },
    GithubAuthProvider: { PROVIDER_ID: 'github.com' },
  };
  return {
    initializeApp: jest.fn(),
    auth: jest.fn(() => mockAuthInstance),
  };
});
  1. Mock StyledFirebaseAuth 组件,避免加载真实组件的异步逻辑,直接渲染测试需要的按钮文本:
// Mock react-firebaseui的认证组件
jest.mock('react-firebaseui/StyledFirebaseAuth', () => {
  return function MockStyledFirebaseAuth() {
    return (
      <div>
        <button>Sign in with Google</button>
        <button>Sign in with Facebook</button>
      </div>
    );
  };
});

添加完上述Mock逻辑后,测试运行时不会调用真实的Firebase服务,也就不会产生异步报错,你原来的测试用例就可以正常执行了。
如果需要测试已登录状态的渲染逻辑,只需要在对应测试用例中修改Mock的onAuthStateChanged回调传入的用户对象即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 07:06:03