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

Firebase Cloud Function测试中能否断言模拟Firestore的读写次数?

完全可以,基于Firebase本地模拟器的测试环境下,你可以通过两种常用方案实现对Firestore读写操作次数的断言校验。

方案一:对Firestore SDK的读写方法打桩统计

这种方案实现简单,适合常规测试场景,通过测试框架的间谍函数统计所有调用过的读写方法即可,不会影响实际的方法执行逻辑,以下是基于Jest测试框架的示例:

  • 第一步:安装所需依赖
npm install --save-dev @firebase/rules-unit-testing firebase-functions-test jest
  • 第二步:编写测试用例
const firebaseFunctionsTest = require('firebase-functions-test')({
  projectId: '你的测试项目ID',
});
const admin = require('firebase-admin');
const myFunctions = require('./index'); // 替换为你的云函数入口文件路径

// 读写计数器
let readCount, writeCount;

// 测试前初始化Admin实例
beforeAll(() => {
  if (admin.apps.length === 0) {
    admin.initializeApp({
      projectId: '你的测试项目ID'
    });
  }
});

// 每次测试前重置计数器、恢复桩函数、清空Firestore数据
beforeEach(async () => {
  readCount = 0;
  writeCount = 0;
  jest.restoreAllMocks();

  // 给读取类方法加统计桩,可根据业务需要补充更多方法
  jest.spyOn(admin.firestore.CollectionReference.prototype, 'get').mockImplementation(function() {
    readCount++;
    return jest.requireActual('@google-cloud/firestore').CollectionReference.prototype.get.apply(this, arguments);
  });
  jest.spyOn(admin.firestore.DocumentReference.prototype, 'get').mockImplementation(function() {
    readCount++;
    return jest.requireActual('@google-cloud/firestore').DocumentReference.prototype.get.apply(this, arguments);
  });

  // 给写入类方法加统计桩,可根据业务需要补充更多方法
  jest.spyOn(admin.firestore.CollectionReference.prototype, 'add').mockImplementation(function() {
    writeCount++;
    return jest.requireActual('@google-cloud/firestore').CollectionReference.prototype.add.apply(this, arguments);
  });
  jest.spyOn(admin.firestore.DocumentReference.prototype, 'set').mockImplementation(function() {
    writeCount++;
    return jest.requireActual('@google-cloud/firestore').DocumentReference.prototype.set.apply(this, arguments);
  });
  jest.spyOn(admin.firestore.DocumentReference.prototype, 'update').mockImplementation(function() {
    writeCount++;
    return jest.requireActual('@google-cloud/firestore').DocumentReference.prototype.update.apply(this, arguments);
  });
  jest.spyOn(admin.firestore.DocumentReference.prototype, 'delete').mockImplementation(function() {
    writeCount++;
    return jest.requireActual('@google-cloud/firestore').DocumentReference.prototype.delete.apply(this, arguments);
  });

  // 清空Firestore模拟器存量数据
  await admin.firestore().recursiveDelete(admin.firestore().collection('messages'));
});

test('addMessage云函数执行对应1次写入、0次读取', async () => {
  // 封装云函数调用方法
  const wrappedAddMessage = firebaseFunctionsTest.wrap(myFunctions.addMessage);
  // 执行云函数
  const res = await wrappedAddMessage({
    query: {
      text: '测试内容'
    }
  });
  // 断言返回结果符合预期
  expect(res.code).toBe(200);
  // 断言读写次数符合预期
  expect(readCount).toBe(0);
  expect(writeCount).toBe(1);
});

方案二:读取模拟器公开操作统计接口

Firebase Firestore模拟器默认会将所有操作记录到内置的统计接口,不需要修改SDK逻辑,统计结果完全和真实运行情况一致,适合对统计准确性要求极高的场景:

模拟器统计接口地址格式:http://<模拟器主机地址>:<Firestore端口>/emulator/v1/projects/<你的测试项目ID>/databases/(default)/operations
默认本地运行的Firestore模拟器地址为localhost:8080

你可以在云函数执行完成后,发送GET请求拉取该接口的返回值,过滤统计write和read类型的操作数量即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 10:06:04