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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:25:17