Eri*_*ndi 5 unit-testing angular-http-interceptors angular angular-unit-test
我已经构建了一个HttpInterceptor紧跟 Angular 文档中的那个。
但是,作为拦截器的一部分,我需要进行异步调用。我用代码的简化版本(但语义相同)创建了一个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;
})
);
}
}
Run Code Online (Sandbox Code Playgroud)
这很简单:
req.url.startsWith())该ConfigurationService有一个简单的string命名属性apiUrl。该SessionService有一个名为几乎同样简单的方法,getToken()它返回一个Promise<string>。
但是,我很难测试这个......
我的实际测试非常简单:
it('should add authorization header for API call', () => {
http.get('bar').subscribe();
httpMock.expectOne(req => req.headers.has('Authorization'));
});
Run Code Online (Sandbox Code Playgroud)
我曾经嘲笑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'));
});
Run Code Online (Sandbox Code Playgroud)
因此,正如我的评论中提到的,修复似乎是使用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'));
}));
Run Code Online (Sandbox Code Playgroud)
虽然这是有道理的,但如果有人能澄清为什么我需要tick()......我认为解决承诺就足够了。我确实尝试使用await http.get().toPromise();(并使用async关键字 - 而不是函数),但这不起作用。
| 归档时间: |
|
| 查看次数: |
2208 次 |
| 最近记录: |