簡體   English   中英

如何測試使用Angular 6+調用observable的攔截器?

[英]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;
            })
        );
    }
}

這很簡單:

  • 檢查我們調用的URL是否需要我們的令牌( 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM