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

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配置存在错误:

  1. HttpClientModule被错误地添加到了providers数组中,它属于模块类,只能在imports中声明。
  2. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 14:20:56