Angular单元测试报错:NullInjectorError缺少Store与HttpClient提供者
解决Angular单元测试中的NullInjectorError问题
我的Angular应用运行正常,但执行自动代码检查的单元测试时测试得分为0,出现以下两个错误:
错误信息
Details:NullInjectorError: R3InjectorError(DynamicTestModule)[CoursesFacade -> Store -> Store]: NullInjectorError: No provider for Store! at NullInjector.get (/autocode/5ce10ff9-8a91-4e7a-bec5-464985f1b430/repository/node_modules/@angular/core/fesm2020/core.mjs:7493:27) at R3Injector.get (/autocode/5ce10ff9-8a91-4e7a-bec5-
NullInjectorError: R3InjectorError(DynamicTestModule)[CoursesService -> HttpClient -> HttpClient]: NullInjectorError: No provider for HttpClient! at NullInjector.get (/autocode/5ce10ff9-8a91-4e7a-bec5-464985f1b430/repository/node_modules/@angular/core/fesm2020/core.mjs:7493:27) at
由于无法修改测试代码,只能通过调整自身代码解决问题。以下是我的app.module.ts和SharedModule代码:
app.module.ts代码
import { NgModule } from "@angular/core"; import { BrowserModule } from "@angular/platform-browser"; import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; import { SharedModule } from "@shared/shared.module"; import { AppComponent } from "@app/app.component"; import { CourseInfoComponent } from "@features/course-info/course-info.component"; import { NotAuthorizedGuard } from "@app/auth/guards/not-authorized.guard"; import { AuthorizedGuard } from "@app/auth/guards/authorized.guard"; import { CoursesStoreService } from "@app/services/courses-store.service"; import { CoursesService } from "@app/services/courses.service"; import { CoursesComponent } from "./features/courses/courses.component"; import { CoursesListComponent } from "./features/courses/courses-list/courses-list.component"; import { AppRoutingModule } from "./app-routing.module"; import { HTTP_INTERCEPTORS, HttpClientModule } from "@angular/common/http"; import { WindowRefService } from "./shared/provides/window.provider"; import { TokenInterceptor } from "./auth/interceptors/token.interceptor"; import { StoreModule } from "@ngrx/store"; import { EffectsModule } from "@ngrx/effects"; import { effects, reducers } from "./store/courses"; import { CoursesFacade } from "./store/courses/courses.facade"; import { CoursesEffects } from "./store/courses/courses.effects"; @NgModule({ declarations: [ AppComponent, CourseInfoComponent, CoursesComponent, CoursesListComponent, ], imports: [ BrowserModule, SharedModule, FontAwesomeModule, AppRoutingModule, HttpClientModule, StoreModule.forRoot(reducers), EffectsModule.forRoot(effects), ], providers: [ AuthorizedGuard, NotAuthorizedGuard, CoursesService, CoursesStoreService, WindowRefService, HttpClientModule, CoursesFacade, CoursesEffects, { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true, }, ], bootstrap: [AppComponent], }) export class AppModule {}
SharedModule代码
import { NgModule } from "@angular/core"; import { CommonModule } from "@angular/common"; import { FontAwesomeModule } from "@fortawesome/angular-fontawesome"; import { ModalComponent } from "./components/modal/modal.component"; import { HeaderComponent, ButtonComponent, InfoComponent, SearchComponent, CourseCardComponent, LoginFormComponent, RegistrationFormComponent, CourseFormComponent, } from "./components"; import { FormsModule, ReactiveFormsModule } from "@angular/forms"; import { DurationPipe } from "./pipes/duration.pipe"; import { CustomDatePipe } from "./pipes/custom-date.pipe"; import { EmailValidatorDirective } from "@shared/directives/email.directive"; const components = [ HeaderComponent, ButtonComponent, InfoComponent, SearchComponent, ModalComponent, CourseCardComponent, LoginFormComponent, RegistrationFormComponent, CourseFormComponent, DurationPipe, CustomDatePipe, EmailValidatorDirective, ]; @NgModule({ declarations: [components], imports: [CommonModule, FontAwesomeModule, FormsModule, ReactiveFormsModule], exports: [components], }) export class SharedModule {}
问题原因及解决方法
原因分析
测试环境的DynamicTestModule未获取到Store和HttpClient的依赖,根源在于你的AppModule配置存在错误:
HttpClientModule被错误地添加到了providers数组中,它属于模块类,只能在imports中声明。CoursesEffects已经通过EffectsModule.forRoot(effects)完成注册,重复添加到providers会导致依赖注入冲突。
修正步骤
修改app.module.ts的providers数组,移除错误添加的依赖:
providers: [ AuthorizedGuard, NotAuthorizedGuard, CoursesService, CoursesStoreService, WindowRefService, CoursesFacade, { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true, }, ],
- 移除
HttpClientModule:它已经在imports中导入,无需在providers中重复声明。 - 移除
CoursesEffects:EffectsModule.forRoot(effects)已经完成该服务的注册,重复添加会干扰测试环境的依赖注入。
修正后,测试环境在加载模块时就能正确获取到Store和HttpClient的依赖,解决NullInjectorError问题。
内容的提问来源于stack exchange,提问作者user28273827332
相关产品推荐
相关产品推荐

