简体   繁体   中英

How to test Angular functions that use http.get?

I finished the Angular tour of heroes and started writing tests for it. Some were pretty easy to write, but when I try to get data from server it just doesn't work. I have read about testing controller, defer, marbles, schedulers and that kind of stuff, but I still have no idea how to proceed. I either get permanent test failures or the test passes with 'SPEC HAS NO EXPECTATIONS', which also brings nothing as it's just essentially an empty test.

//Test
it('#updateHero() works', waitForAsync(inject([HeroService], (service: HeroService) => {
let testHero = {
  id: 42,
  name: 'TestHero'
} as Hero
service.updateHero(testHero).subscribe()
service.getHero(42).subscribe(hero => expect(hero.name).toBe('TestHero'))
})));
//service
getHero(id: number): Observable<Hero> {
const url = `${this.heroesUrl}/${id}`
return this.http.get<Hero>(url).pipe(
  tap(_ => this.messageService.add(`fetched hero id=${id}`)),
  catchError(this.handleError<Hero>(`getHero id=${id}`)))}


updateHero(hero: Hero): Observable<any> {
return this.http.put(this.heroesUrl, hero, this.httpOptions).pipe(
  tap(_ => this.messageService.add(`updated hero id=${hero.id}`)),
  catchError(this.handleError<any>('updateHero'))
)}

In some other tests I get the same problem, they just don't get anything from my services, however the actual application works perfectly.

My colleagues didn't manage to actually answer my question, except for some strange decisions like mocking the whole server response.

After a long time of trying out anything I could find, I came up with the following solution:

...
beforeEach(async () => {
let router = {
  snapshot: {
    paramMap: {
      get: () => 1, // represents the bookId
    },
  },
};

await TestBed.configureTestingModule({
  declarations: [ DetailComponent ],
  imports: [ HttpClientTestingModule ],
  providers: [
    {
      provide: ActivatedRoute,
      useValue: router
    },
  ],
})
.compileComponents();

...
});

it('http.get hero works', () => {
const heroes: Hero[] = [
  { id: 1, name: 'Fake Batman1', imgSrc: '../assets/Batman.jpg', score: -5, commentary: 'FAKE!!!!!' },
  { id: 2, name: 'Fake Batman2', imgSrc: '../assets/Batman.jpg', score: -5, commentary: 'FAKE!!!!!' },
  { id: 3, name: 'Cool Batman', imgSrc: '../assets/Batman.jpg', score: 20, commentary: 'The coolest batman ever' },
  { id: 4, name: 'Fake Batman3', imgSrc: '../assets/Batman.jpg', score: -5, commentary: 'FAKE!!!!!' },
  { id: 5, name: 'Batman', imgSrc: '../assets/Batman.jpg', score: 3, commentary: 'No opinion' },
  { id: 6, name: 'Fake Batman4', imgSrc: '../assets/Batman.jpg', score: -5, commentary: 'FAKE!!!!!' },
]
const req = httpTestingController.expectOne('api/heroes/1');
expect(req.request.method).toEqual('GET');
req.flush(heroes[2]);
httpTestingController.verify();
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM