You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Jasmine或ng-mocks模拟Firebase的onAuthStateChanged方法

解决方案

要模拟直接导入的@angular/fire/auth中的函数,核心是将导入方式改为模块对象导入,这样Jasmine就能通过spyOn拦截函数调用。以下是具体实现步骤:

1. 修改原服务的导入与调用方式

将单独导入的函数改为从模块对象中引用,这样后续才能被 spy 拦截:

// 原导入方式
// import { Auth, getAuth, onAuthStateChanged, User } from '@angular/fire/auth';

// 修改为模块对象导入
import * as angularFireAuth from '@angular/fire/auth';

// 服务内的代码调整为:
const app = initializeApp(environment.firebase);
this.auth = angularFireAuth.getAuth(app);
this.db = getDatabase();

// 使用模块对象调用 onAuthStateChanged
angularFireAuth.onAuthStateChanged(this.auth, (user) => {
    // ... 原有逻辑
});

2. 在测试文件中模拟onAuthStateChanged

在测试用例中,通过spyOn模拟模块对象上的onAuthStateChanged方法,根据不同场景传入模拟用户或null:

import { TestBed } from '@angular/core/testing';
import { YourAuthService } from './your-auth.service';
import * as angularFireAuth from '@angular/fire/auth';

describe('YourAuthService', () => {
  let service: YourAuthService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      // 无需额外注入,因为我们直接模拟模块函数
    });
    service = TestBed.inject(YourAuthService);
  });

  it('应处理已登录状态', () => {
    // 创建模拟用户实例
    const mockUser: angularFireAuth.User = {
      uid: 'test-user-id',
      email: 'test@example.com',
      // 按需添加其他必要属性
    } as angularFireAuth.User;

    // 模拟 onAuthStateChanged:调用回调时传入模拟用户
    spyOn(angularFireAuth, 'onAuthStateChanged').and.callFake((auth, callback) => {
      callback(mockUser);
      // 返回空的 unsubscribe 函数,避免报错
      return () => {};
    });

    // 初始化服务(触发 onAuthStateChanged 调用)
    service = TestBed.inject(YourAuthService);

    // 断言已登录状态下的逻辑是否执行正确
    // 例如:expect(service.currentUser).toEqual(mockUser);
  });

  it('应处理未登录状态', () => {
    // 模拟 onAuthStateChanged:调用回调时传入 null
    spyOn(angularFireAuth, 'onAuthStateChanged').and.callFake((auth, callback) => {
      callback(null);
      return () => {};
    });

    service = TestBed.inject(YourAuthService);

    // 断言未登录状态下的逻辑是否执行正确
    // 例如:expect(service.currentUser).toBeNull();
  });
});

关键说明

  • 改用模块对象导入是核心:单独导入的函数是直接引用,Jasmine 无法拦截;而模块对象的属性可以被spyOn劫持。
  • callFake用于自定义函数的执行逻辑,这里直接调用传入的回调函数,模拟 auth 状态变化的触发。
  • 务必返回一个空的Unsubscribe函数,避免因返回值不符合类型定义导致的测试报错。

内容的提问来源于stack exchange,提问作者lukasniessen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 05:07:02