Angular-RxJs-Testing-防止嵌套的catchError被执行

问题描述 投票:0回答:1

我想测试一个 http 错误拦截器情况,其中下一个句柄最初抛出一个错误,并且嵌套的可观察对象发出一个值。问题是,虽然“switchMap”的代码按照测试的预期执行,但嵌套的 catchError 的代码也被触发。

预期的行为是在执行

return next.handle(cloneReq)
时终止代码。 我想了解如何重构测试用例的代码以防止在这种情况下触发嵌套的 catchError 代码。

错误拦截器.ts

intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<any> {
  return next.handle(request).pipe(
      catchError((error: ErrorResponse) => {
           if (error.status === 401) {
                   return this.authService
                           .refreshToken(localStorage.getItem('item')!)
                           .pipe(
                                switchMap((res: LoginResponse) => {
                                //some code here           
        
                                return next.handle(cloneReq);
                            }),
                            catchError(x => {
                                this.authService.logOut();
                                return _throwError();
                })
              );
           }

  })
}

error.interceptor.spec.ts

it('should done some things', () => {
      const error = {
        status: 401,
        ignore: false,
        message: 'test-error',
      };

      const loginResponse: LoginResponse = {
        accessToken: 'test-access-token123',
      };

      spyOnProperty(service, 'tokenRefreshed', 'get').and.returnValue(false);
      spyHttpHandler.handle.and.returnValue(throwError(() => error));
      spyRefreshToken.and.returnValue(of(loginResponse));

      service.intercept(spyHttpRequest, spyHttpHandler).subscribe();

      expect(spyLogout).not.toHaveBeenCalled();
    });
angular rxjs jasmine rxjs-marbles
1个回答
0
投票

显然经过大量调试后,问题是“httphandler”的“handle”函数仅被监视一次,但对该函数的实际调用是两次。

所以,当代码到达这里时

返回 next.handle(cloneReq);

因为间谍会为函数的所有后续调用抛出错误,所以调用嵌套的 catchError 块。

通过将间谍更改为以下内容可以解决问题:

spyHttpHandler.handle.and.returnValues(
    throwError(() => error),
    of(10)
  );

通过此更改,handle 方法的第二次实际调用将返回一个值为 10 的虚拟可观察量,并且测试将在不调用嵌套的 catchError 块的情况下终止。

© www.soinside.com 2019 - 2024. All rights reserved.