如何在 Angular 中覆盖 HttpErrorResponse

How to coverage HttpErrorResponse in Angular

我正在尝试覆盖 Jasmin 框架的 HttpErrorResponse 代码覆盖率,但它没有覆盖。

组件

onSubmit(form: NgForm) {
    if (navigator.onLine) {
      const headers = new HttpHeaders().set(InterceptorSkipHeader, '')
      this.loginService.login(form.value, headers).subscribe(data => {
        const serverData = JSON.parse(JSON.stringify(data));
        if (serverData.status == 'success') {
          localStorage.setItem(GlobalVariables.AUTHERIZATION_TOEKN, serverData.access_token);
          localStorage.setItem(GlobalVariables.USER_ID, serverData.userId);
          this.router.navigate([""]);
        } else {
          this.toast.error(serverData.message, "Fail!");
        }
      }, (errorResponse: HttpErrorResponse) => {
        if (errorResponse.error instanceof ErrorEvent) {
          this.toast.error(errorResponse.error.message, "Client Error");
        } else {
          this.toast.error(errorResponse.error.message, "Server Error");
        }
      });
    } else {
      this.toast.error(GlobalVariables.CHECK_INTERNET_CONNECTION, "Fail!");
    }
  }

测试class

 it('Check login component', () => {
    const errorResponse = new HttpErrorResponse({
      error: '404 error',
      status: 404,
      statusText: 'Not Found'
    });
    let testForm = <NgForm>{
      value: {
        userName: "sample",
        password: "sample"
      }
    };
    const headers = new HttpHeaders();
    let response;
    spyOn(service,'login').and.returnValue(of(errorResponse));
    service.login(testForm.value,headers).subscribe(
      data => fail('Should have failed with 404 error'),
      (error: HttpErrorResponse) => {
        expect(error.status).toEqual(404);
        expect(error.error).toContain('404 error');
      }
    );
    component.onSubmit(testForm);
  });

未覆盖代码

(errorResponse: HttpErrorResponse) => {
        if (errorResponse.error instanceof ErrorEvent) {
          this.toast.error(errorResponse.error.message, "Client Error");
        } else {
          this.toast.error(errorResponse.error.message, "Server Error");
        }
      });
    } else {
      this.toast.error(GlobalVariables.CHECK_INTERNET_CONNECTION, "Fail!");
    }

这是因为在您的测试中调用的是服务,而组件代码中没有涉及的代码。

您需要调用 component.onSubmit 而不是 service.login.subscribe.

您需要对成功案例和错误案例进行单独测试(对每个案例进行两次测试以覆盖 ifelse 路径)。它们基本上在您模拟 loginService.login 方法的方式上有所不同,当然在预期结果上也有所不同。

对于成功的情况,您模拟loginService.login如下(if和[=14=的successResponse不同] 路径):

spyOn(service,'login').and.returnValue(of(successResponse));

对于error的情况,loginService.login需要如下所示进行mock:

if路径...

const errorEvent = <ErrorEvent> { message: 'something bad happened' };
const errorResponse = new HttpErrorResponse({
    error: errorEvent
});    
spyOn(service,'login').and.returnValue(throwError(errorResponse));

else路径...

const errorResponse = new HttpErrorResponse({
    error: '404 error',
    status: 404,
    statusText: 'Not Found'
});    
spyOn(service,'login').and.returnValue(throwError(errorResponse));