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

如何用Jest模拟同一属性下的不同对象?(Firebase React场景)

How to mock Firebase's auth property that is both a function and an object in Jest?

Problem Description

I'm using Firebase in a React component, and the auth property on the Firebase object acts as both a function (when calling auth()) and an object (to access properties like GoogleAuthProvider). Here's my setup:

/App.js

import React, { useEffect } from 'react';
import { firebase } from './be/firebase';

function App() {
  useEffect(() => {
    console.log('@App');
    console.log(firebase.auth.GoogleAuthProvider.PROVIDER_ID);
    firebase.auth().onAuthStateChanged(/* stuff */);
  }, []);
  return <div></div>;
}

export default App;

/be/firebase.js

import * as firebase from 'firebase/app';
import 'firebase/auth';

const firebaseConfig = { /* my config */ };
if (!firebase.apps.length) {
  firebase.initializeApp(firebaseConfig);
}

export { firebase };

The code works fine in production, but I'm struggling to mock this dual-behavior auth property in Jest. My initial mock attempt looks like this:

/App.test.js

jest.mock('./be/firebase', () => {
  return {
    firebase: {
      auth: {
        GoogleAuthProvider: { PROVIDER_ID: 'mock', },
        onAuthStateChanged: jest.fn(),
      },
    }
  };
});

This throws an error: TypeError: _firebase.firebase.auth is not a function because my mock only treats auth as an object, not a function that can be called.


Solution

Ah, I see the issue here! Firebase's auth is tricky because it's both a function (when you call auth()) and an object that holds static properties like GoogleAuthProvider directly on it. Your mock needs to replicate this dual behavior. Here's the fix:

/App.test.js

jest.mock('./be/firebase', () => {
  // 1. Create a mock auth function that returns an auth instance object
  const mockAuth = jest.fn(() => ({
    onAuthStateChanged: jest.fn()
  }));
  
  // 2. Attach the static GoogleAuthProvider property directly to the mock function
  mockAuth.GoogleAuthProvider = { PROVIDER_ID: 'mock' };

  return {
    firebase: {
      auth: mockAuth
    }
  };
});

Explanation

  • We first define mockAuth as a Jest mock function. When you call firebase.auth() in your component, this function will return an object with the mocked onAuthStateChanged method — just like the real Firebase auth instance.
  • Then we add the GoogleAuthProvider property directly to the mockAuth function itself. This lets you access firebase.auth.GoogleAuthProvider exactly as you do in production code.
  • This setup perfectly mirrors Firebase's actual structure, where auth is callable (to get the auth instance) and also hosts static properties.

If you need to mock other auth-related features later, just extend this pattern: attach static properties to the mockAuth function, and add instance methods to the object it returns.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 12:12:46