Testing Angular inject (in HTTP services)


The Angular inject has made waves.

Developers love it! 🥳 🥳 🥳

But with changes come challenges.

For example, when using the new Angular inject function you might run into dependency injection errors when trying to test.

Today we're going to talk about specifically testing a service that uses the HttpClient via the inject function.

With the new static method runInInjectionContext we're able to make testing the inject function much easier.

The runInInjectionContext allows us to run a given function in the context of the given injector that belongs to our TestBed.

Let's say we have an HTTP service that fetches heroes.

import { HttpClient } from '@angular/common/http';
import { inject, Injectable } from '@angular/core';
import { Observable } from 'rxjs';

export interface Hero {
  id: number;
  name: string;
}

@Injectable({
  providedIn: 'root'
})
export class HeroesService {
  getHeroes(): Observable<Hero[]> {
    return inject(HttpClient).get<Hero[]>('https://angular-heroes.firebaseio.com/heroes.json');
  }
}

We can test the getHeroes function with the help of TestBed.runInInjectionContext.

import { TestBed } from '@angular/core/testing';
import {
  HttpTestingController,
  provideHttpClientTesting,
} from '@angular/common/http/testing';

import { HeroesService } from './heroes.service';
import { provideHttpClient } from '@angular/common/http';

describe('HeroesService', () => {
  let service: HeroesService;
  let controller: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [provideHttpClient(), provideHttpClientTesting()]
    });
    controller = TestBed.inject(HttpTestingController);
    service = TestBed.inject(HeroesService);
  });

  it('should fetch heroes', () => {
    TestBed.runInInjectionContext(service.getHeroes).subscribe((result) => {
      expect(result).toBeTruthy();
    });

    controller.expectOne('https://angular-heroes.firebaseio.com/heroes.json').flush([]);
  });
});

And with that, you're done!

Have a great Angular time,

signature

Daniel Kreider