angular: httpClient.get из разрешенного Promise не проходит тест - PullRequest
0 голосов
/ 04 сентября 2018

Мне трудно написать тест для службы, которая выполняет вызов httpClient.get(...) angular изнутри then разрешенного обещания. Внутри всего приложения (т. Е. Не теста) все работает как положено, обещания разрешаются, и из данных разрешенного обещания извлекается URL для httpClient.get вызова

Однако в тесте, даже если обещание выполнено (then(...) выполнено), httpClient.get(...), по-видимому, никогда не выполняется.

Чтобы проиллюстрировать проблему, я создал отрывок, основанный на Http Guide Testing от angular. Смотрите все это здесь: 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() тест снова будет успешным.

В настоящее время я не могу обойти созданную там дополнительную тему, но это не должно влиять на проблему, которую я имею с обещанием.

Я также не могу обойти обещание, потому что оно возвращено из сторонней библиотеки. Я попытался обернуть его в Observable (fromPromise), но это тоже не помогло.

См. Все здесь: https://stackblitz.com/edit/angular-y21e6j

1 Ответ

0 голосов
/ 06 сентября 2018

с некоторой помощью я нашел проблему ... Согласно 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);
    }));
...