角度:已解决的Promise的httpClient.get测试失败

时间:2018-09-04 12:14:10

标签: angular promise rxjs angular-test

我很难为服务编写测试,该服务从已解决的承诺的httpClient.get(...)内部调用angular的then。在整个应用程序(即非测试)内部,一切都按预期工作,承诺得以解决,并且从已解决的承诺数据中提取了httpClient.get调用的URL

在测试中,即使已解决了承诺(执行了then(...),也从未明显执行过httpClient.get(...)

为了说明这个问题,我根据angular的Http Guide Testing创建了一个片段。在这里查看全部内容:https://stackblitz.com/edit/angular-y21e6j

有希望的测试失败了:

  

错误:预期对标准“匹配URL:   api / heroes”,找不到。

一般来说,我有两个功能:

  getHeroes(): Observable<any> {
    const sub = new Subject();
    this.http.get<any>(this.heroesUrl)
      .pipe(
      catchError(this.handleError('getHeroes', []))
      ).subscribe(data => sub.next(data));
    return sub;
  }


  notWorking(): Observable<any> {
    const sub = new Subject();
    const promise = Promise.resolve([this.heroesUrl]);
    promise.then(url => {
      console.log('Promise is resolved');
      this.http.get<any>(url[0])
        .pipe(
        catchError(this.handleError('getHeroes', []))
        ).subscribe(data => sub.next(data));
    })
    return sub;
  }

我还复制了角度指南中的测试,并为第二种方法插入了一个。他们看起来像这样:

it('should return expected heroes (called once)', () => {

  heroService.getHeroes().subscribe(
    heroes => expect(heroes).toEqual(expectedHeroes, 'should return expected heroes'),
    fail
  );

  // HeroService should have made one request to GET heroes from expected URL
  const req = httpTestingController.expectOne(heroService.heroesUrl);
  expect(req.request.method).toEqual('GET');

  // Respond with the mock heroes
  req.flush(expectedHeroes);
});

    it('should also work with promise', () => {

  heroService.notWorking().subscribe(
    heroes => expect(heroes).toEqual(expectedHeroes, 'should return expected heroes'),
    fail
  );

  // HeroService should have made one request to GET heroes from expected URL
  const req = httpTestingController.expectOne(heroService.heroesUrl);
  expect(req.request.method).toEqual('GET');

  // Respond with the mock heroes
  req.flush(expectedHeroes);
});

请注意,一旦您删除了承诺,然后从notWorking()中进行测试,测试就会再次成功。

我目前无法解决在那里创建的其他主题,但这不应该影响我所承诺的问题。

我也无法兑现承诺,因为它是从第3方库返回的。我尝试将其包装到Observable(fromPromise)上,但这也无济于事。

在此处查看整个内容:https://stackblitz.com/edit/angular-y21e6j

1 个答案:

答案 0 :(得分:0)

在一些帮助下,我发现了问题...根据https://www.joshmorony.com/testing-asynchronous-code-with-fakeasync-in-angular fakeAsync()flushMicroTasks()一起使用...的确确实有效:

it('should also work with promise and fakeAsync', fakeAsync(() => {

      heroService.notWorking().subscribe(
        heroes => expect(heroes).toEqual(expectedHeroes, 'should return expected heroes'),
        fail
      );
      flushMicrotasks();

      // HeroService should have made one request to GET heroes from expected URL
      const req = httpTestingController.expectOne(heroService.heroesUrl);
      expect(req.request.method).toEqual('GET');

      // Respond with the mock heroes
      req.flush(expectedHeroes);
    }));