Я использую приложение Angular 6 Tour of Heroes и пытаюсь написать модульные тесты для HeroService.getHeroes()
.
HeroService определяется как:
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
import { Hero } from './hero';
import { MessageService } from './message.service';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
@Injectable({ providedIn: 'root' })
export class HeroService {
private heroesUrl = 'api/heroes'; // URL to web api
constructor(
private http: HttpClient,
private messageService: MessageService) { }
/** GET heroes from the server */
getHeroes (): Observable<Hero[]> {
return this.http.get<Hero[]>(this.heroesUrl)
.pipe(
tap(heroes => this.log('fetched heroes')),
catchError(this.handleError('getHeroes', []))
);
}
...
/**
* Handle Http operation that failed.
* Let the app continue.
* @param operation - name of the operation that failed
* @param result - optional value to return as the observable result
*/
private handleError<T> (operation = 'operation', result?: T) {
return (error: any): Observable<T> => {
// TODO: send the error to remote logging infrastructure
console.error(error); // log to console instead
// TODO: better job of transforming error for user consumption
this.log(`${operation} failed: ${error.message}`);
// Let the app keep running by returning an empty result.
return of(result as T);
};
}
/** Log a HeroService message with the MessageService */
private log(message: string) {
this.messageService.add(`HeroService: ${message}`);
}
}
Мои модульные тесты:
import { TestBed, inject } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { HeroService } from './hero.service';
import { MessageService } from './message.service';
import { Hero } from './hero';
const mockData = [
{ id: 1, name: 'Hulk' },
{ id: 2, name: 'Thor' },
{ id: 3, name: 'Iron Man' }
] as Hero[];
describe('Hero Service', () => {
let heroService;
let httpTestingController: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule
],
providers: [HeroService, MessageService]
});
httpTestingController = TestBed.get(HttpTestingController);
this.mockHeroes = [...mockData];
this.mockHero = this.mockHeroes[0];
this.mockId = this.mockHero.id;
heroService = TestBed.get(HeroService);
});
afterEach(() => {
httpTestingController.verify();
});
it('should be created', () => {
expect(heroService).toBeTruthy();
});
describe('getHeroes', () => {
it('should return mock heroes', () => {
spyOn(heroService, 'handleError');
spyOn(heroService, 'log');
heroService.getHeroes().subscribe(
heroes => expect(heroes.length).toEqual(this.mockHeroes.length),
fail
);
const req = httpTestingController.expectOne(heroService.heroesUrl);
expect(req.request.method).toEqual('GET');
req.flush(this.mockHeroes);
expect(heroService.handleError).not.toHaveBeenCalled();
expect(heroService.log).toHaveBeenCalledTimes(1);
});
});
});
Тесты не выполняются с:
Сбой является неожиданным, так как кажется, что действительно вызывается HeroService.handleError
, что не относится к тестам.Почему во время выполнения теста вызывается HeroService.handleError
и как мне исправить свои юнит-тесты?