Angular 测试http侦听器-在侦听器返回之前调用expect
我有一个简单的Angular 测试http侦听器-在侦听器返回之前调用expect,angular,rxjs,angular-http-interceptors,Angular,Rxjs,Angular Http Interceptors,我有一个简单的HttpInterceptor,用于设置加载状态。这是密码 @Injectable({ providedIn: 'root', }) export class LoaderHttpInterceptor implements HttpInterceptor { constructor(private _loadingService: LoadingService) {} intercept( req: HttpRequest<any>, n
HttpInterceptor
,用于设置加载状态。这是密码
@Injectable({
providedIn: 'root',
})
export class LoaderHttpInterceptor implements HttpInterceptor {
constructor(private _loadingService: LoadingService) {}
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
const id = uuid();
this._loadingService.startLoading(id);
return next
.handle(req)
.pipe(finalize(() => this._loadingService.completeLoading(id)));
}
}
在最后两个测试中,在拦截器中的finalize
操作符之前调用了测试中的expect
语句,我不知道为什么。我的印象是,直到拦截器完成,http调用才会返回
如果我在第二个测试中添加pipe(delay(1000))
,它将工作,但这是错误的。在第三次测试中这样做没有什么区别
我希望有人能给我解释一下
谢谢。我想重新(阅读)文档和源代码会有所帮助。我认为测试需要是异步的,因为正常的http请求是异步的,但是HttpTestingController
是同步发出的。测试需要像这样编写:
it('should call loader service completeLoading on success', () => {
const url = faker.internet.url();
httpClient.get(url, { responseType: 'text' }).subscribe();
controller.expectOne(url).flush({}, { status: 200, statusText: ''} );
controller.verify();
expect(mockLoadingService.completeLoading).toBeCalledTimes(1);
});
为什么你认为
下一步
和错误
处理程序应该在完成
之后执行?@yurzui-你知道为什么之前执行它们,因为这就是我要问的吗?拦截器应该转换流,那么为什么在返回http响应后调用finalize
,或者我完全误解了这一点?因为finalize是在observable完成或出错时调用的。好吧,我想我只是误解了http请求管道的工作方式。在深入研究Angular源代码之后,发现拦截器在http请求的Observable中运行,因此在http请求Observable完成之前,finalize
不会被调用。
it('should call loader service completeLoading on success', () => {
const url = faker.internet.url();
httpClient.get(url, { responseType: 'text' }).subscribe();
controller.expectOne(url).flush({}, { status: 200, statusText: ''} );
controller.verify();
expect(mockLoadingService.completeLoading).toBeCalledTimes(1);
});