Как проверить перехватчик, который вызывает наблюдаемое в Angular 6+? - PullRequest
0 голосов
/ 15 февраля 2019

Я построил HttpInterceptor, который очень похож на тот, который описан в угловой документации.

Однако мне нужно было сделать асинхронный вызов как часть моего перехватчика.Я создал StackBlitz с упрощенной версией кода (но идентичной по семантике).

Перехватчик выглядит следующим образом:

export class AuthInterceptor implements HttpInterceptor {
    constructor(private session: SessionService, private config: ConfigurationService) {}

    intercept(req: HttpRequest<any>, next: HttpHandler) {
        const apiRoot = this.config.apiUrl;
        if (apiRoot && req.url.startsWith(apiRoot)) {
            return this.addAuth(req).pipe(switchMap(x => next.handle(x)));
        } else {
            return next.handle(req);
        }
    }

    private addAuth(original: HttpRequest<any>): Observable<HttpRequest<any>> {
        return from(this.session.getToken()).pipe(
            map(token => {
                const req = original.clone({
                    setHeaders: { Authorization: `Bearer ${token}` }
                });
                return req;
            })
        );
    }
}

Это довольно просто:

  • проверьте, требует ли URL-адрес, по которому мы звоним, наш токен (req.url.startsWith())
  • , если да, затем извлеките наш токен и добавьте его в качестве заголовка
  • если нет, просто продолжите конвейер

ConfigurationService имеет простое string свойство с именем apiUrl.SessionService имеет почти такой же простой метод с именем getToken(), который возвращает Promise<string>.

Код работает, как и ожидалось: response with authorization header

Однако,Я испытываю трудности с тестированием этого ...

Мой настоящий тест очень прост:

it('should add authorization header for API call', () => {
    http.get('bar').subscribe();
    httpMock.expectOne(req => req.headers.has('Authorization'));
});

Я правильно высмеял getToken() и apiUrl, чтобы apiUrl='bar'и getToken() возвращает Promise.resolve('foobar').Кажется, проблема заключается в только при прохождении пути addAuth().Если я проверяю на встречный случай, он работает:

it('should NOT add authorization header for non-API call', () => {
    http.get('baz').subscribe();
    httpMock.expectOne(req => !req.headers.has('Authorization'));
});

1 Ответ

0 голосов
/ 18 февраля 2019

Итак, как упоминалось в одном из моих комментариев, исправление, по-видимому, заключается в использовании fakeAsync() и tick() следующим образом:

beforeEach(()=>{
    spyOn(sessionService, 'getToken').and.returnValue(Promise.resolve('foobar'));
});
it('should add authorization header for API call', fakeAsync(() => {
    http.get('bar').subscribe();
    tick();
    httpMock.expectOne(req => req.headers.has('Authorization'));
}));

Хотя это имеет смысл, если кто-нибудь сможет уточнить, почемуМне нужно tick() ... Я думал, что решение обещания будет достаточно.Я попытался использовать await http.get().toPromise(); (и использовать ключевое слово async, а не функцию), но это не сработало.

...