如何使用Jest正确模拟Google Cloud Storage的File实例getSignedUrl方法
正确模拟getSignedUrl的实现方案
原有模拟代码失效原因
jest.mock的第一个参数需传入完整的模块路径,原代码填写的'File'不属于合法模块标识,无法匹配到@google-cloud/storage的导出内容- 需要模拟的是
File类实例上的getSignedUrl方法,而非模块根导出的静态方法 - 原业务代码中用数组解构接收异步返回值,
getSignedUrl本身返回的是解析为数组的Promise,原模拟返回的对象结构不匹配业务逻辑
正确实现代码
全局模拟(所有测试用例生效)
将模拟代码放在测试文件顶部所有import语句之前即可:
jest.mock('@google-cloud/storage', () => { const originalModule = jest.requireActual('@google-cloud/storage'); // 模拟File类构造函数 const MockFile = jest.fn().mockImplementation(() => { return { // 模拟实例的getSignedUrl方法,返回符合结构的Promise getSignedUrl: jest.fn().mockResolvedValue(['http://mock-signed-url.example.com']), // 如果用到File的其他实例方法,可以在这里补充对应的模拟逻辑 }; }); return { ...originalModule, File: MockFile, }; }); // 后续的业务代码import正常写即可 import { File } from '@google-cloud/storage'
单测试用例局部模拟(仅指定用例生效)
如果不需要全局替换File类,只想在单个测试用例中模拟返回值,可以使用以下写法:
test('测试签名URL生成逻辑', async () => { const mockBlob = new File(); // 仅当前用例覆盖getSignedUrl返回值 jest.spyOn(mockBlob, 'getSignedUrl').mockResolvedValue(['http://mock-local-url.example.com']); // 调用你的业务逻辑 const [url] = await mockBlob.getSignedUrl({ action: 'read', expires: Date.now() + 60 * 1000, contentType: mimetype }); // 验证逻辑正确性 expect(url).toBe('http://mock-local-url.example.com'); expect(mockBlob.getSignedUrl).toHaveBeenCalledTimes(1); })
如果你是通过
firebase-admin/storage引入的File实例,仅需要将jest.mock的第一个参数替换为对应的firebase-admin存储模块路径即可,模拟逻辑完全一致。
内容的提问来源于stack exchange,提问作者Rodrigo
相关产品推荐
相关产品推荐

