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

如何用Jest模拟Firebase的signInWithEmailAndPassword?报错求助

解决Jest模拟Firebase signInWithEmailAndPassword 的问题

问题根源

报错 TypeError: Cannot read properties of undefined (reading 'then') 说明 signInWithEmailAndPassword(auth, email, password) 返回了undefined,而非预期的Promise。同时你的mock存在两个核心问题:

  1. Firebase Auth的导入方式错误,mock结构不匹配实际导出
  2. getAuth未返回有效实例,导致业务代码中传递给signInWithEmailAndPassword的auth参数无效

修复步骤

1. 修正Firebase Auth的Mock结构

调整测试文件中的mock,确保getAuth返回有效实例,signInWithEmailAndPassword返回Promise:

import React from 'react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import Login from './Login';
// 用命名导入匹配firebase/auth的实际导出规则
import * as firebaseAuth from 'firebase/auth';

jest.mock('firebase/auth', () => {
  // 创建mock的auth实例
  const mockAuthInstance = {};
  return {
    getAuth: jest.fn(() => mockAuthInstance),
    signInWithEmailAndPassword: jest.fn(() => 
      Promise.resolve({ user: { uid: 'test-user-id' } })
    ),
  };
});

2. 修正测试用例的断言逻辑

业务代码中直接调用signInWithEmailAndPassword函数,断言需指向mock的该函数,同时补充输入框填充步骤(确保登录逻辑触发):

describe('Login', () => {
  it('Logs user in', async () => {
    render(<Login />);
    
    // 先填充邮箱和密码(匹配你组件的输入框label)
    fireEvent.change(screen.getByLabelText(/email/i), { 
      target: { value: 'test@example.com' } 
    });
    fireEvent.change(screen.getByLabelText(/password/i), { 
      target: { value: 'test123' } 
    });

    fireEvent.click(screen.getByText(/Log in/i));
    
    await waitFor(() => {
      expect(firebaseAuth.signInWithEmailAndPassword).toHaveBeenCalledWith(
        firebaseAuth.getAuth(),
        'test@example.com',
        'test123'
      );
    });
  });
});

3. 对齐业务代码的导入逻辑

确保业务函数signIn中的Firebase方法导入与mock匹配:

import { signInWithEmailAndPassword, getAuth } from 'firebase/auth';
import { getFirestore, collection } from 'firebase/firestore';
import { initializeApp } from 'firebase/app';

const app = initializeApp(config);
const auth = getAuth(app);
const db = getFirestore(app);

export const signIn = async (email:string, password:string) => {
  // 确保调用方式与mock匹配:传递auth实例、邮箱、密码
  await signInWithEmailAndPassword(auth, email, password);
  const usersRef = collection(db, 'Users');
  // ...后续业务逻辑
};

4. 补充Firestore的Mock(如果需要)

如果业务代码用到Firestore的方法,需要同步mockfirebase/firestore:

jest.mock('firebase/firestore', () => ({
  getFirestore: jest.fn(() => ({})),
  collection: jest.fn(() => ({})),
  // 其他用到的Firestore方法需逐一mock
}));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 10:01:46