Jest中是否有Mockito.any等价物?如何测试带参数的异步函数
针对异步函数postStampService的测试方案
一、最佳测试实践
- 正确处理异步逻辑:测试异步函数时必须用
await等待执行完成,否则Jest会在函数实际运行前结束测试,导致断言失效。除非你预期函数会抛出特定错误并需要验证,否则无需用try/catch包裹。 - 验证调用细节:除了确认
checkAuthHeader被调用,还要验证它的调用参数是否符合预期,提升测试严谨性。
二、Mock postStampService的函数参数
你需要为每个参数创建符合类型要求的mock对象,以下是针对各参数的具体实现:
1. Mock req: functions.https.Request
创建包含业务所需属性的模拟对象,比如鉴权需要的headers:
const mockReq = { headers: { authorization: 'Bearer test-token' }, body: { /* 你的请求体数据 */ } } as functions.https.Request;
2. Mock res: functions.Response<any>
模拟响应对象的核心方法(如status、send),方便后续验证响应行为:
const mockRes = { status: jest.fn().mockReturnThis(), // 支持链式调用需返回自身 send: jest.fn() } as unknown as functions.Response<any>;
3. Mock admin: any
如果函数用到admin的特定方法,可直接mock模块或创建局部模拟对象:
// 方式1:mock整个firebase-admin模块 jest.mock('firebase-admin', () => ({ auth: jest.fn().mockReturnValue({ verifyIdToken: jest.fn().mockResolvedValue({ uid: 'test-uid' }) }) })); const mockAdmin = require('firebase-admin'); // 方式2:手动创建局部mock const mockAdmin = { auth: jest.fn().mockReturnValue({ /* 所需方法实现 */ }) };
4. Mock defaultFirestore: Firestore
模拟Firestore实例及所需方法,比如collection、add:
const mockFirestore = { collection: jest.fn().mockReturnValue({ add: jest.fn().mockResolvedValue({ id: 'test-stamp-id' }) }) } as unknown as Firestore;
整合mock参数后的测试代码示例:
it("should call checkAuthHeader with correct request", async () => { // 准备mock参数 const mockReq = { headers: { authorization: 'Bearer test' } } as functions.https.Request; const mockRes = { status: jest.fn().mockReturnThis(), send: jest.fn() } as unknown as functions.Response<any>; const mockAdmin = {}; const mockFirestore = {} as Firestore; // 执行异步函数 await postStampService(mockReq, mockRes, mockAdmin, mockFirestore); // 断言checkAuthHeader被调用且传入正确参数 expect(checkAuthHeader).toHaveBeenCalledWith(mockReq); });
三、Jest中类似Mockito.any的匹配器
Jest提供了几个等价匹配器,覆盖不同场景:
jest.any(Constructor):匹配指定构造函数创建的任意实例,比如匹配任意Request对象:expect(checkAuthHeader).toHaveBeenCalledWith(jest.any(functions.https.Request));expect.anything():匹配任何非null/undefined的值,不限制类型:expect(checkAuthHeader).toHaveBeenCalledWith(expect.anything());expect.any(Constructor):和jest.any功能一致,用于expect断言中:expect(checkAuthHeader).toHaveBeenCalledWith(expect.any(Object));
内容的提问来源于stack exchange,提问作者quinzo
相关产品推荐
相关产品推荐

