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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 00:02:34