[英]how do I test an interceptor which calls an observable with Angular 6+?
我已經構建了一個HttpInterceptor
Angular文檔中的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;
})
);
}
}
這很簡單:
req.url.startsWith()
) ConfigurationService
有一個名為apiUrl
的簡單string
屬性。 SessionService
有一個幾乎同樣簡單的名為getToken()
方法,它返回一個Promise<string>
。
但是,我很難測試這個......
我的實際測試非常簡單:
it('should add authorization header for API call', () => {
http.get('bar').subscribe();
httpMock.expectOne(req => req.headers.has('Authorization'));
});
我已經正確地apiUrl='bar'
getToken()
和apiUrl
,以便apiUrl='bar'
和Promise.resolve('foobar')
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'));
});
所以,正如我的一條評論中提到的,修復似乎是使用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
關鍵字 - 而不是函數),但這不起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.