Как сделать, чтобы мой тест Жасмин достиг этого обратного вызова внутри mergeMap? - PullRequest
0 голосов
/ 12 декабря 2018

Я работаю с Angular6 и пытаюсь, чтобы мой тест Жасмин достиг обратного вызова внутри mergeMap ниже, но после нескольких дней работы я просто не могу этого сделать.

callback inside mergeMap highlighted

Мой тест корректно возвращает метод обновления, но, похоже, он не проходит через канал.

Этополный метод, в котором я тестирую:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<any> {
    if (
      this.jwtInterceptor.isWhitelistedDomain(req) &&
      !this.jwtInterceptor.isBlacklistedRoute(req)
    ) {
      const newRequest = req.clone();
      return next.handle(newRequest).pipe(
        tap(() => {
          const token = this.jwtHelper.tokenGetter();
          if (token) {
            const expirationTime = this.jwtHelper
              .getTokenExpirationDate()
              .getTime();
            const expirationLeft = expirationTime - Date.now();
            const expired =
              expirationLeft > 0 && expirationLeft < 5 * 60 * 1000;
            if (expired && !this.isUpdating) {
              this.isUpdating = true;
              return this.refresh().pipe(
                mergeMap(() => { // this is the unreachable part
                  return this.jwtInterceptor.intercept(req, next);
                })
              );
            }
          }
        }),
        catchError(err => {
          if (err instanceof HttpErrorResponse && err.status === 401) {
            this.router.navigate([this.config.routeToGoIfNotLoggedIn]);
          }
          return throwError(err);
        })
      );
    } else {
      return next.handle(req);
    }
  }

Вот мой метод this.refresh () вернул:

refresh(): Observable<any> {
    const refreshObservable = this.authAPI.refreshToken();
    const refreshSubject = new ReplaySubject<any>(1);
    refreshSubject.subscribe(
      data => {
        localStorage.setItem('token', data.jwt);
        this.isUpdating = false;
      },
      err => {
        this.isUpdating = false;
        this.userLoggedService.removeUserLoggedAndToken();
      }
    );

    refreshObservable.subscribe(refreshSubject);
    return refreshSubject;
  }
}

, и это мой this.authAPI.refreshToken (), запущенный внутриrefresh ():

  refreshToken() {
    return this.http.get(`${this.config.baseAPIUrl}refreshToken`);
  }

HTTP-вызов корректно перехватывается в моем httpTestingController, и окончательное ожидание - запуск this.jwtInterceptor.intercept (req, next).

Это мойСпецификация для части, которую я терплю неудачу:

it('should call Refresh method if token is expiring in 5 minutes', () => {
    const nowInMillisec = Number(new Date());
    const FourMinutesFromNow = nowInMillisec + 4 * 60000;
    spyOn(
      jwtService,
      'getTokenExpirationDate'
    ).and.returnValue(new Date(FourMinutesFromNow));

    const jwtInterceptor = TestBed.get(JwtInterceptor);
    const spyOnJwtInterceptor = spyOn(jwtInterceptor, 'intercept');

    dummyService.fakeHttpCall().subscribe();
    httpTestingController.expectOne(
      `${MockAuthConfig.baseAPIUrl}user/fake-call`
    );

    const callbackHttpFired = httpTestingController.expectOne(
      `${MockAuthConfig.baseAPIUrl}refreshToken`
    );
    expect(callbackHttpFired.request.url).toEqual(
      `${MockAuthConfig.baseAPIUrl}refreshToken`
    );
    expect(spyOnJwtInterceptor).toHaveBeenCalled(); // this spy is never fired... :(
  });

Есть идеи?Большое спасибо !!

1 Ответ

0 голосов
/ 12 декабря 2018

Использование done() здесь жизненно важно, поскольку вызов subscribe является асинхронным, остальная часть вашего теста запускается до выхода subscribe.Кроме того, вы должны проверить метод refresh отдельно.Сначала проверьте, что refresh был вызван в intercept

. Затем сигнатура должна быть изменена с помощью

it('should call Refresh method if token is expiring in 5 minutes', (done) => {    
  ...
  jwtInterceptor.intecept.subscribe(() => { 
    expect(spyOnJwtInterceptor).toHaveBeenCalled();
    done();
  });
}

, чтобы тестовый метод дождался вызова метода done ().И ожидание будет идти по плану.

...