使用Jest对Firebase Admin函数做单元测试并指定mock返回值
解决方案
问题核心原因
- 你原先的mock对象没有正确替换实际导入的
firebase-admin依赖,mock的链式调用结构不符合真实调用逻辑 admin.auth().createUser返回的是Promise对象,业务代码是异步逻辑,测试没有用async/await处理异步返回- 没有利用Jest提供的类型推导方法解决返回类型标注问题
正确实现步骤
1. 全局mock firebase-admin模块
在测试文件顶部导入依赖后直接mock整个模块,结构和真实调用对齐:
import * as admin from 'firebase-admin'; // 全局mock firebase-admin jest.mock('firebase-admin', () => ({ auth: jest.fn().mockReturnValue({ createUser: jest.fn() }) }));
2. 改写测试用例
使用jest.mocked获得类型推导,自定义返回值,处理异步逻辑:
import { HttpException, HttpStatus } from '@nestjs/common'; import { AccountService } from './account.service'; import * as admin from 'firebase-admin'; import type { UserRecord } from 'firebase-admin/auth'; jest.mock('firebase-admin', () => ({ auth: jest.fn().mockReturnValue({ createUser: jest.fn() }) })); // 获得带Firebase官方类型的mock方法 const mockCreateUser = jest.mocked(admin.auth().createUser); describe('AccountService', () => { let service: AccountService; const mockRegisterDto = { email: 'test@test.com', password: '123456', displayName: 'test user' }; const expectedAccount = { uid: 'mock-uid-123', email: 'test@test.com', emailVerified: false, displayName: 'test user', message: 'User is successfully registered!', }; afterEach(() => { jest.clearAllMocks(); }); beforeEach(() => { service = new AccountService(); }); it('注册成功时返回正确的Account对象', async () => { // 自定义createUser的resolve值,类型完全匹配Firebase定义 mockCreateUser.mockResolvedValue({ uid: expectedAccount.uid, email: expectedAccount.email, emailVerified: expectedAccount.emailVerified, displayName: expectedAccount.displayName, disabled: false, } as UserRecord); const result = await service.registerUser(mockRegisterDto); expect(result).toEqual(expectedAccount); // 额外断言createUser调用参数符合预期 expect(mockCreateUser).toHaveBeenCalledWith({ email: mockRegisterDto.email, emailVerified: false, password: mockRegisterDto.password, displayName: mockRegisterDto.displayName, disabled: false, }); }); it('注册失败时抛出对应HttpException', async () => { const mockError = new Error('邮箱已被注册'); mockCreateUser.mockRejectedValue(mockError); await expect(service.registerUser(mockRegisterDto)).rejects.toThrow( new HttpException(`Bad Request Error creating new user: ${mockError.message}`, HttpStatus.BAD_REQUEST) ); }); });
内容的提问来源于stack exchange,提问作者Louw
相关产品推荐
相关产品推荐

