单元测试中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
相关产品推荐
相关产品推荐

