如何在Jest中Mock Firebase的admin.messaging().sendMulticast()函数?
如何Mock Firebase的admin.messaging().sendMulticast()函数
问题场景
待测试的sendNotification函数逻辑:
- 创建通知记录
- 获取用户的FCM令牌列表
- 如果令牌列表不为空,调用
admin.messaging().sendMulticast()发送推送通知
当前测试代码存在mock顺序错误、admin.messaging()mock方式不正确的问题,需要修正。
解决方案
要正确mockadmin.messaging().sendMulticast(),需分步骤处理嵌套的mock结构,同时确保所有mock操作在调用待测试函数前完成,并添加断言验证逻辑。
修正后的完整测试代码
it('should send notification via FCM', async function(){ // 1. 准备测试数据 const mockNotificationId = 'mock-notif-id'; const mockFCMTokens = ['112233']; const notificationData = { id: mockNotificationId, title: 'notification title', message: 'notification message', type: 'global', created_at: new Date() }; // 2. Mock 依赖函数(必须在调用待测试函数前设置) // Mock 创建通知的方法 db.moxyNotification.addNotification.mockResolvedValue(notificationData); // Mock 获取FCM令牌的方法 jest.spyOn(userFCMTokenService, 'fetchUserFCMToken') .mockResolvedValue(mockFCMTokens); // 3. 正确Mock admin.messaging()及sendMulticast const mockSendMulticast = jest.fn().mockResolvedValue({ successCount: 1 }); jest.spyOn(admin, 'messaging') .mockReturnValue({ sendMulticast: mockSendMulticast }); // 4. 调用待测试函数 await NotificationService.sendNotification({ userId: 'notificationId', // 修正原测试中的拼写错误usedId -> userId title: 'notification title', message: 'notification message', type: 'global' }); // 5. 添加断言验证 // 验证sendMulticast是否被调用 expect(mockSendMulticast).toHaveBeenCalled(); // 验证调用参数是否符合预期 expect(mockSendMulticast).toHaveBeenCalledWith(expect.objectContaining({ tokens: mockFCMTokens, data: expect.objectContaining({ id: mockNotificationId, title: notificationData.title }) })); // 验证获取FCM令牌的方法是否被正确调用 expect(userFCMTokenService.fetchUserFCMToken).toHaveBeenCalledWith('notificationId'); });
关键说明
- mock顺序:所有依赖的mock必须在调用
sendNotification前设置,否则待测试函数执行时会使用真实的依赖实现。 - 嵌套mock处理:
admin.messaging()是一个函数,调用后返回包含sendMulticast的对象,因此需要让messaging的mock返回一个带有mock版sendMulticast的对象,而非直接mocksendMulticast。 - 异步mock适配:因为待测试函数中使用了
await,异步方法的mock要使用mockResolvedValue而非mockReturnValue,确保Promise能正确解析。 - 断言验证:通过断言确认mock函数的调用情况,确保业务逻辑符合预期,比如
sendMulticast的调用参数、调用次数等。
内容的提问来源于stack exchange,提问作者IdontEvenEven
相关产品推荐
相关产品推荐

