使用Karma与Jasmine进行Angular自动化测试时遭遇NullInjectorError问题求助
解决Angular测试中
NullInjectorError: No provider for InjectionToken angularfire2.app.options!的问题 这个错误的核心原因很明确:你的ArchiveComponent依赖了AngularFireAuth服务,但在测试模块中没有配置AngularFire的必要依赖项,导致Angular无法找到angularfire2.app.options这个注入令牌(也就是Firebase的配置信息)。
下面给你两种有效的解决方案,你可以根据测试需求选择:
方案1:在测试模块中配置完整的AngularFire依赖
这种方式和你在AppModule中的配置一致,适合需要测试组件与Firebase真实交互的场景:
修改archive.component.ts的测试代码,添加AngularFire相关模块的导入和配置:
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { Router } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; import { ArchiveComponent } from './archive.component'; // 导入AngularFire相关模块 import { AngularFireModule } from '@angular/fire'; import { AngularFireAuthModule } from '@angular/fire/auth'; // 导入测试环境的Firebase配置(如果没有单独的测试环境,也可以用生产环境的environment) import { environment } from 'src/environments/environment'; describe('ArchiveComponent', () => { let component: ArchiveComponent; let fixture: ComponentFixture<ArchiveComponent>; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ArchiveComponent], imports: [ RouterTestingModule, // 初始化AngularFire并传入Firebase配置 AngularFireModule.initializeApp(environment.firebase), // 导入组件依赖的AngularFireAuth模块 AngularFireAuthModule ] }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(ArchiveComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); });
方案2:Mock AngularFireAuth服务(推荐用于单元测试)
如果你的目标是单元测试组件本身的逻辑,而不是测试与Firebase的交互,那么mock掉AngularFireAuth服务会更高效,也不需要依赖真实的Firebase配置:
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { Router } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; import { ArchiveComponent } from './archive.component'; // 导入AngularFireAuth import { AngularFireAuth } from '@angular/fire/auth'; import { of } from 'rxjs'; // 创建一个mock的AngularFireAuth服务,模拟组件需要的方法和属性 const mockAngularFireAuth = { // 模拟authState observable,根据组件实际使用情况调整返回值 authState: of(null), // 如果组件用到了signOut等方法,也可以在这里mock signOut: jasmine.createSpy('signOut').and.returnValue(Promise.resolve()) }; describe('ArchiveComponent', () => { let component: ArchiveComponent; let fixture: ComponentFixture<ArchiveComponent>; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ArchiveComponent], imports: [RouterTestingModule], providers: [ // 用mock的服务替代真实的AngularFireAuth { provide: AngularFireAuth, useValue: mockAngularFireAuth } ] }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(ArchiveComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); });
额外提示
如果你的ArchiveComponent还依赖其他Firebase服务(比如AngularFirestore或AngularFireStorage),需要对应地在测试模块中导入相关模块,或者mock对应的服务,确保所有依赖都能被正确注入。
内容的提问来源于stack exchange,提问作者Tootsie
相关产品推荐
相关产品推荐

