如何用Jest模拟firebase-admin/database的Reference.prototype.update方法?
如何用Jest监视Firebase实时数据库的update方法
因为firebase-admin里的database.Reference是接口而非导出的类,没法直接用jest.spyOn(database.Reference.prototype, "update"),这里给你两种可行的方案:
方案一:通过临时实例拿原型做Spy
你可以先创建一个临时的Reference实例,再通过它获取原型对象,进而对update方法进行监视:
import admin from "firebase-admin"; import * as database from "firebase-admin/database"; import { X } from "./your-file"; // 导入你的函数X // 先创建临时实例获取原型 const tempRef = database.getDatabase().ref(); const updateSpy = jest.spyOn(Object.getPrototypeOf(tempRef), "update").mockResolvedValue(); test("函数X会调用update方法", async () => { await X(); // 断言update被调用 expect(updateSpy).toHaveBeenCalled(); // 还能检查调用参数是否符合预期 // expect(updateSpy).toHaveBeenCalledWith(expect.objectContaining({ key: "value" })); }); // 测试完成后恢复原方法 afterEach(() => { updateSpy.mockRestore(); });
所有通过db.ref()生成的实例都共用同一个原型,所以这种方式能覆盖到所有update调用。
方案二:直接模拟数据库引用
如果想彻底隔离真实SDK,也可以直接mockgetDatabase和ref的返回值,手动提供带mock方法的对象:
import admin from "firebase-admin"; import * as database from "firebase-admin/database"; import { X } from "./your-file"; // mock整个database模块 jest.mock("firebase-admin/database", () => { // 定义mock的update方法 const mockUpdate = jest.fn().mockResolvedValue(); const mockRef = jest.fn(() => ({ update: mockUpdate })); const mockGetDatabase = jest.fn(() => ({ ref: mockRef })); // 保留原模块的其他导出,避免测试报错 return { ...jest.requireActual("firebase-admin/database"), getDatabase: mockGetDatabase, }; }); test("函数X正确调用update", async () => { const mockDb = database.getDatabase(); const mockHelloRef = mockDb.ref("hello"); await X(); expect(mockHelloRef.update).toHaveBeenCalled(); });
这种方式完全脱离真实Firebase服务,适合纯单元测试场景,灵活性更高。
内容的提问来源于stack exchange,提问作者Akasha
相关产品推荐
相关产品推荐

