如何同时将Firebase Auth模拟为对象与函数?适配登录场景Mock
嘿,我来帮你搞定这个Firebase Auth的Mock问题!你遇到的核心点在于:Firebase的firebase.auth既是一个包含静态属性(比如FacebookAuthProvider)的对象,又是一个可调用的函数(调用后返回Auth实例,包含signInAndRetrieveDataWithCredential这类方法)。
要模拟这种“既是函数又是对象”的结构,我们可以利用JavaScript的特性——函数本身就是对象,所以我们可以先创建一个函数,再给它直接附加静态属性。下面是完整的解决方案:
完整Mock代码(以Jest为例,也可以适配其他测试框架)
// 1. 先定义模拟的Auth实例,包含你需要的方法 const mockAuthInstance = { // 模拟signInAndRetrieveDataWithCredential,返回resolved的用户数据 signInAndRetrieveDataWithCredential: jest.fn().mockResolvedValue({ user: { uid: "123", email: "test@example.com" } }), // 修正拼写(Firebase官方是onAuthStateChanged),模拟登录状态监听 onAuthStateChanged: jest.fn().mockImplementation(callback => { // 立即触发回调,模拟已登录状态 callback({ uid: "123", email: "test@example.com" }); // 返回空的取消订阅函数(符合Firebase API规范) return () => {}; }) }; // 2. 创建auth函数,调用后返回上面的实例 const mockAuth = () => mockAuthInstance; // 3. 给auth函数添加静态属性:FacebookAuthProvider mockAuth.FacebookAuthProvider = { // 模拟credential方法,返回简单的凭证对象 credential: jest.fn().mockReturnValue({ providerId: "facebook.com" }) }; // 4. 整合到firebase对象中 const firebase = { auth: mockAuth };
适配非Jest环境的版本(纯原生JS)
如果不用测试框架,直接写普通函数即可:
const mockAuthInstance = { signInAndRetrieveDataWithCredential: async () => ({ user: { uid: "123", email: "test@example.com" } }), onAuthStateChanged: callback => { callback({ uid: "123", email: "test@example.com" }); return () => {}; } }; const mockAuth = () => mockAuthInstance; mockAuth.FacebookAuthProvider = { credential: (accessToken) => ({ providerId: "facebook.com", accessToken // 保留传入的token,方便测试时验证 }) }; const firebase = { auth: mockAuth };
为什么这样可行?
- 当你调用
firebase.auth()时,会执行我们定义的mockAuth函数,返回模拟的Auth实例,就能调用signInAndRetrieveDataWithCredential方法。 - 当你访问
firebase.auth.FacebookAuthProvider时,直接获取到我们附加在mockAuth函数上的静态属性,就能调用credential方法生成凭证。
这个Mock完美匹配你提供的Facebook登录场景,能够让你的代码正常执行,同时也方便后续扩展其他Auth方法(比如signOut、createUser等)。
内容的提问来源于stack exchange,提问作者Ilja
相关产品推荐
相关产品推荐

