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

单元测试中Mock admin.firestore().collection().get()失败求助

解决单元测试中Mock Firestore的问题

我明白你现在卡在单元测试Mock Firestore的环节了——你想Mock这段业务代码:

const firestore = admin.firestore();
const users = await firestore.collection('users').get();

但自己写的Stub方案没生效,咱来拆解问题,一步步搞定它。

问题出在哪?

你之前的Mock写法忽略了链式调用的逻辑:原代码是依次调用firestore() → collection('users') → get(),但你让collection直接返回了Promise,跳过了get()这一步,自然和业务代码的调用流程对不上,Mock也就没法生效。

正确的Mock方案(基于Sinon)

我们需要按链式调用的顺序,逐个Stub每个环节的返回值,保证每个方法都能返回可继续调用下一个方法的对象:

  • 先Stub admin.firestore()方法,让它返回一个带有collection方法的对象
  • 为collection('users')定义返回值,这个返回值必须包含get()方法
  • 让get()方法返回符合Firestore结构的模拟数据(比如包含docs数组,每个文档对象要有data()方法)

具体代码实现如下:

// 1. 先Stub admin.firestore方法
const firestoreStub = sinon.stub(admin, 'firestore');

// 2. 模拟users集合的对象,包含get方法
const mockUsersCollection = {
  get: sinon.stub().resolves({
    // 模拟Firestore QuerySnapshot的结构
    docs: [
      { data: () => ({ id: 'user1', username: 'testUser' }) },
      { data: () => ({ id: 'user2', username: 'anotherUser' }) }
    ]
  })
};

// 3. 让firestore实例的collection方法,当传入'users'时返回模拟集合
firestoreStub.returns({
  collection: sinon.stub().withArgs('users').returns(mockUsersCollection)
});

小提示

  • 测试结束后记得恢复Stub,避免影响其他测试用例:firestoreStub.restore()
  • 如果需要Mock多个不同的集合,可以用callsFake来根据路径返回对应的模拟集合,比如:
    collection: sinon.stub().callsFake((path) => {
      if (path === 'users') return mockUsersCollection;
      if (path === 'posts') return mockPostsCollection;
      // 其他路径的默认返回
      return { get: sinon.stub().resolves({ docs: [] }) };
    })
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:52:07