AbhiRam
AbhiRam

Reputation: 2061

How to coverage HttpErrorResponse in Angular

I am trying to coverage below HttpErrorResponse code coverage by Jasmin framework but its not getting to cover.

component

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!");
    }
  }

test 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);
  });

not covered code

(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!");
    }

Upvotes: 0

Views: 210

Answers (2)

uminder
uminder

Reputation: 26150

You need individual tests for the successful and the error cases (two tests for each case to have the if and the else path covered). They basically differ in the way you mock the loginService.login method and of course in the expected result.

For the successful case, you mock loginService.login as follows (with different successResponse for the if and the else path):

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

For the error case, loginService.login needs to be mocked as shown below:

if path...

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

else path...

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

Upvotes: 1

kvetis
kvetis

Reputation: 7331

It is because in your test you're calling the service whereas the code not covered is in the component code.

You need to call the component.onSubmit instead of service.login.subscribe.

Upvotes: 0

Related Questions