angularangular-httpclientangular-unit-test

Angular 18 - No provider for Http Client used on service for component Unit test


I have an application using Angular 18, and I have one component that uses a service. That service calls HttpClient, gets a list of entities and the component uses that on the constructor.

The unit test for the service is working fine with the provideHttpClient and provideHttpClientTest. However, the component fails because of failed injection of the HttpClient

Chrome 126.0.0.0 (Windows 10) CardListComponent should create FAILED NullInjectorError: R3InjectorError(Standalone[CardListComponent])[HttpClient -> HttpClient -> HttpClient]: NullInjectorError: No provider for HttpClient! error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ 'HttpClient', 'HttpClient', 'HttpClient' ] })

Below is the code for the unit test. I have tried many different approaches found here, and even ones on the official documentation, but none seem to work.

describe('CardListComponent', () => {
  let component: CardListComponent;
  let fixture: ComponentFixture<CardListComponent>;

  let cardService: CardServiceService;

  const cardServiceMock: jasmine.SpyObj<CardServiceService> = jasmine.createSpyObj('CardServiceService', ['getAllCards']);

 beforeEach(async () => {
   await TestBed.configureTestingModule({
     imports: [CardListComponent],
     providers: [
       provideHttpClient,
       provideHttpClientTesting,
       CardListComponent,
         {
        provide: CardServiceService,
         useValue: cardServiceMock,
       },
    ],
  }).compileComponents();

fixture = TestBed.createComponent(CardListComponent);

component = fixture.componentInstance;

fixture.detectChanges();

});

it('should create', () => {
  expect(component).toBeTruthy();
});

Solution

  • provideHttpClient and provideHttpClientTesting are functions which you need to call. You are missing the parentheses.

    providers: [
      provideHttpClient(),
      provideHttpClientTesting(),
    ],
    

    See: https://angular.dev/guide/http/setup

    In the unit tests, skipping the parentheses doesn't lead to a TypeScript error, because in TestBed.configureTestingModule, the providers are typed as any[]. There is an open feature request to improve the typings: https://github.com/angular/angular/issues/37178