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,
Daniel Kreider