Angular 16+AngularFire单元测试报错:需已废弃的AngularFireModule
版本信息
- @angular/fire:7.6.1
- @angular:16.0.0
问题
项目集成AngularFire后运行正常,但编写单元测试时,系统提示需要已废弃的AngularFireModule。
认证服务代码
import { Injectable } from '@angular/core'; import { from, Observable } from 'rxjs'; import { Auth, signInWithEmailAndPassword, authState, createUserWithEmailAndPassword, UserCredential, } from '@angular/fire/auth'; @Injectable({ providedIn: 'root', }) export class AuthService { currentUser$ = authState(this.auth); constructor(private auth: Auth) {} signUp(email: string, password: string): Observable<UserCredential> { return from(createUserWithEmailAndPassword(this.auth, email, password)); } login(email: any, password: any): Observable<any> { return from(signInWithEmailAndPassword(this.auth, email, password)); } logout(): Observable<any> { return from(this.auth.signOut()); } }
解决方法
新版本AngularFire采用依赖注入Auth实例的方式,单元测试无需导入废弃的AngularFireModule,直接模拟Auth服务即可:
1. 构建模拟Auth对象
创建包含服务所需方法的模拟实例,同时处理authState返回的Observable:
import { of } from 'rxjs'; import { UserCredential } from '@angular/fire/auth'; const mockAuth = jasmine.createSpyObj('Auth', [ 'signOut', 'signInWithEmailAndPassword', 'createUserWithEmailAndPassword' ]);
2. 配置TestBed并编写测试用例
在测试模块中提供模拟的Auth实例,同时模拟authState函数:
import { TestBed } from '@angular/core/testing'; import { AuthService } from './auth.service'; import { Auth } from '@angular/fire/auth'; import * as AngularFireAuth from '@angular/fire/auth'; import { of } from 'rxjs'; describe('AuthService', () => { let service: AuthService; let mockAuth: jasmine.SpyObj<Auth>; beforeEach(async () => { mockAuth = jasmine.createSpyObj('Auth', [ 'signOut', 'signInWithEmailAndPassword', 'createUserWithEmailAndPassword' ]); await TestBed.configureTestingModule({ providers: [ AuthService, { provide: Auth, useValue: mockAuth } ] }).compileComponents(); service = TestBed.inject(AuthService); // 模拟authState返回的用户状态流 spyOn(AngularFireAuth, 'authState').and.returnValue(of(null)); }); it('should be created', () => { expect(service).toBeTruthy(); }); it('should call signInWithEmailAndPassword on login', (done) => { const testEmail = 'test@example.com'; const testPassword = '123456'; const mockCredential = {} as UserCredential; mockAuth.signInWithEmailAndPassword.and.returnValue(Promise.resolve(mockCredential)); service.login(testEmail, testPassword).subscribe({ next: (credential) => { expect(credential).toEqual(mockCredential); expect(mockAuth.signInWithEmailAndPassword).toHaveBeenCalledWith(testEmail, testPassword); done(); } }); }); });
通过这种方式,既规避了对废弃模块的依赖,又能正常完成Auth服务的单元测试。
内容的提问来源于stack exchange,提问作者sivansh kamat
相关产品推荐
相关产品推荐

