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
相关产品推荐
相关产品推荐

