使用React Testing Library和Jest时如何Mock Firebase的onAuthStateChanged
错误原因
你在Firebase配置文件中导出的auth是已经调用app.auth()后生成的实例对象,不是可执行函数,但你当前的mock将auth定义为了函数,只有执行auth()才能拿到带onAuthStateChanged的返回对象,和你实际业务代码里直接调用auth.onAuthStateChanged的逻辑不匹配,因此会报属性不存在的错误。
修复方案
修改你的mock代码,直接将auth定义为带onAuthStateChanged方法的对象即可,同时注意onAuthStateChanged需要返回一个unsubscribe取消订阅函数,匹配React useEffect的清理逻辑:
jest.mock("../../../firebase", () => ({ // 直接导出对象,不是函数 auth: { onAuthStateChanged: jest.fn((callback) => { // 可根据测试需要默认触发回调,比如默认返回未登录状态 callback(null); // 返回模拟的取消订阅函数 return jest.fn(); }), }, // 如果你业务代码里还用到了导出的database、storage等其他对象,也要在这里补充对应的mock,避免其他报错 database: {}, storage: {}, chats: {}, firebase: {}, }));
进阶用法(模拟不同登录状态)
如果你需要测试登录、未登录等不同场景,可以把模拟的onAuthStateChanged暴露出来,在测试用例里手动触发回调传不同的用户值:
// 先定义可复用的mock回调 const mockOnAuthStateChanged = jest.fn((callback) => { return jest.fn(); }); jest.mock("../../../firebase", () => ({ auth: { onAuthStateChanged: mockOnAuthStateChanged, }, // 其他导出的mock database: {}, storage: {}, chats: {}, firebase: {}, })); // 测试用例中模拟用户登录场景 test("已登录状态下渲染用户信息", () => { // 手动触发onAuthStateChanged的回调,传入模拟的用户数据 mockOnAuthStateChanged.mockImplementation((callback) => { callback({ uid: "test123", email: "test@example.com" }); return jest.fn(); }); // 后续执行组件渲染和断言逻辑 });
内容的提问来源于stack exchange,提问作者Alex Masinde
相关产品推荐
相关产品推荐

