Firebase Storage单元测试求助:如何Mock存储桶及测试方式
Firebase Storage 单元测试的 Mock 方案
好问题!Firebase Storage 的 Mock 测试和 Realtime Database 确实有共通点,但不能直接照搬 firebase-mock 的思路——因为这个库主要针对 Realtime Database 和 Auth 做了支持,对 Storage 的覆盖非常有限。下面给你几种实用的 Mock 存储桶的方案:
1. 官方推荐:使用 @firebase/rules-unit-testing
这是 Firebase 官方推出的测试库,既能验证 Storage 的安全规则,也能模拟完整的存储桶操作,适合需要测试规则+业务逻辑的场景。
示例代码:
const fs = require('fs'); const { initializeTestEnvironment, assertSucceeds, assertFails } = require('@firebase/rules-unit-testing'); describe('Firebase Storage 操作测试', () => { let testEnv; // 初始化测试环境,加载你的 Storage 规则并创建 Mock 存储桶 beforeAll(async () => { testEnv = await initializeTestEnvironment({ storage: { rules: fs.readFileSync('./storage.rules', 'utf8'), // 你的 Storage 规则文件 buckets: [{ name: 'test-bucket-123' }] // 模拟的存储桶名称 } }); }); // 测试后清理环境 afterAll(async () => { await testEnv.cleanup(); }); it('未认证用户应该无法上传文件', async () => { const storage = testEnv.unauthenticatedContext().storage(); const fileRef = storage.bucket('test-bucket-123').file('private/file.txt'); // 断言上传操作会失败 await assertFails(fileRef.putString('敏感内容')); }); it('认证用户可以上传到公开目录', async () => { const storage = testEnv.authenticatedContext('user-123').storage(); const fileRef = storage.bucket('test-bucket-123').file('public/avatar.png'); // 断言上传操作成功 await assertSucceeds(fileRef.putString('图片内容')); }); });
2. 手动 Mock:适合仅测试业务逻辑
如果你的测试不需要验证 Storage 规则,只是想确保自己的函数正确调用了 Storage 的 API,可以用 Jest(或其他测试框架)手动 Mock firebase/storage 模块。
首先创建 Mock 文件(比如 __mocks__/firebase/storage.js):
// 模拟 Storage 文件的方法 const mockFile = { putString: jest.fn().mockResolvedValue({ metadata: { name: 'test-file.txt' } }), getSignedUrl: jest.fn().mockResolvedValue(['https://example.com/test-file.txt']) }; // 模拟存储桶 const mockBucket = { file: jest.fn().mockReturnValue(mockFile) }; // 模拟 Storage 实例 const mockStorage = { bucket: jest.fn().mockReturnValue(mockBucket) }; // 导出 Mock 的方法 module.exports = { getStorage: jest.fn().mockReturnValue(mockStorage) };
然后在测试文件中使用这个 Mock:
const { getStorage } = require('firebase/storage'); const uploadFileToStorage = require('./your-storage-function'); // 你的业务函数 // 启用 Mock jest.mock('firebase/storage'); describe('业务函数测试', () => { it('应该正确调用 Storage 的上传方法', async () => { // 调用你的业务函数 await uploadFileToStorage('测试内容', 'test-file.txt'); // 断言 Storage 方法被正确调用 const storageInstance = getStorage(); expect(storageInstance.bucket).toHaveBeenCalledWith('your-real-bucket-name'); const bucket = storageInstance.bucket(); expect(bucket.file).toHaveBeenCalledWith('test-file.txt'); const file = bucket.file(); expect(file.putString).toHaveBeenCalledWith('测试内容'); }); });
3. 第三方库:mock-firebase-storage
有一个第三方库专门针对 Firebase Storage 做了 Mock,你可以直接安装使用:
npm install mock-firebase-storage --save-dev
示例用法:
const MockFirebaseStorage = require('mock-firebase-storage'); describe('使用第三方 Mock 库测试', () => { let storage; beforeEach(() => { storage = new MockFirebaseStorage(); }); it('应该能模拟文件上传', async () => { const file = storage.bucket('test-bucket').file('demo.txt'); await file.putString('hello world'); // 验证文件是否存在 const savedFile = await storage.bucket('test-bucket').file('demo.txt').get(); expect(savedFile).toBeDefined(); }); });
总结一下:如果需要测试规则,优先用官方的 @firebase/rules-unit-testing;如果只测业务逻辑,手动 Mock 或者第三方库都可以。firebase-mock 确实不适合用来 Mock Storage,别浪费时间在上面啦!
内容的提问来源于stack exchange,提问作者Tom Edwards
相关产品推荐
相关产品推荐

