如何用Jest模拟Firebase的signInWithEmailAndPassword?报错求助
解决Jest模拟Firebase
signInWithEmailAndPassword 的问题 问题根源
报错 TypeError: Cannot read properties of undefined (reading 'then') 说明 signInWithEmailAndPassword(auth, email, password) 返回了undefined,而非预期的Promise。同时你的mock存在两个核心问题:
- Firebase Auth的导入方式错误,mock结构不匹配实际导出
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
相关产品推荐
相关产品推荐

