Unit testing of catcherror pipe function in angular service
Asked Answered
Z

1

7

I try to understand how to test this function. From (err)=>{ line, it's showing as an uncovered statement. service.ts

Deletevote(inp) {
   console.log(inp);
     
   return this.http.post(environment.apiUrl + '/api/reset/abc', inp).pipe(
      catchError((err) => {
         console.log('error caught in service');
         console.error(err);
         return throwError(err);
      })
   );
}

I have created this test case for positive flow, but err part is still not covered. Please guide me about how to create the error.

service.spec.ts

const Mockcolor = 'green';
const MockGen = 'male';

it('submitnominGreen', () => {
    service.Deletevote(DeleteObj).subscribe((posts) =>{
      expect(posts).toEqual([Mockcolor,MockGen], 'should check mock data');
    });
    const req =  httpTestCtrl.expectOne(environment.apiUrl + '/api/reset/abc');
    expect(req.request.method).toBe('POST');
    expect(req.cancelled).toBeFalsy();
    req.flush([Mockcolor,MockGen])
});
Zymase answered 14/7, 2021 at 13:39 Comment(15)
Did you read angular.io/guide/http#testing-for-errors?Acropetal
Yes but how should i code for my function?Zymase
They don't have pipe map in their code.Zymase
You can't expect the documentation to cover every possible kind of consuming code. That shows how to make an error happen in the test, then you have to apply that to your specific circumstances.Acropetal
I am new contributor and I need code wise help. Unit testing doesnot have much reference material.Zymase
It has loads of reference material, in the official docs alone there's what I've pointed you to as well as this whole section: angular.io/guide/testing.Acropetal
Throwing errors for my code for httpClientZymase
Again you cannot expect the documentation, or anyone else's resource, to show your specific code. It's your job to apply the general information to your specific case. If you can't provide a minimal reproducible example of your attempt to do so, you might as well delete this question - this isn't a code-writing service.Acropetal
it('submitnominGreen', () => { service.Deletevote(DeleteObj).subscribe((posts) =>{ expect(posts).toEqual([Mockcolor,MockGen], 'should check mock data'); }); const req = httpTestCtrl.expectOne(environment.apiUrl + '/api/reset/abc'); expect(req.request.method).toBe('POST'); expect(req.cancelled).toBeFalsy(); req.flush([Mockcolor,MockGen]) }); I tried this but still it's not covering error part. Please guide for errors part nowZymase
Please edit the question. But you don't actually seem to be creating an error state, so it's no surprise that part's not covered - maybe try actually applying what the documentation suggests.Acropetal
Done everything, now please guide me codewise.Zymase
No you haven't. You have one test, that appears to be for the happy path. Of course the other branch isn't covered.Acropetal
Copy the code in your angular project or stackblitz and solve the problem, if you really want to!Zymase
Okay, For the last time I am asking what basic requirements do you want me to provide? P.S. I am not getting how to create error so I can't give the error input test case.Zymase
Welcome to SO community, Sakthy Rupini! you did a great job refining the question. It would be beneficial for you and the community to finish the introductory tour stackoverflow.com/tour. It would help to increase your chances to get help. And would give you a badge (: Probably some points as well, which would give you more permissions hereFarra
F
1

First of all, the code inside the subscribe of the unit test would not be executed. Karma would wait for all the sync execution to be finished and would consider the test finished before the async callback would be executed. As a solution, you might use the done callback to indicate when is the test finished manually.

You did a great job leveraging the HttpTestingModule for testing. It allows you to test the errors easily as well. Instead of req.flush you might use the req.error method to simulate the HTTP error.

it('submitnominGreen', (done) => {
    const mockError = {error: 'someError'} as ErrorEvent;
    service.Deletevote(DeleteObj).subscribe(() => {}, (thrownError) =>{
      expect(thrownError.error).toEqual(mockError);
      done();
    });
    const req =  httpTestCtrl.expectOne(environment.apiUrl + '/api/reset/abc');
    req.error(mockError);
});

Take a look into the Error handling section of this nice article: Testing Angular HTTP Communication. It would be of help for some other scenarios as well.

Farra answered 17/7, 2021 at 7:51 Comment(6)
I tried this code but in req.error line it's throwing this error Argument of type 'Error' is not assignable to parameter of type 'ErrorEvent'. Type 'Error' is missing the following properties from type 'ErrorEvent': colno, error, filename, lineno, and 22 more.ts(2345)Zymase
Now this is the error. Expected object to be a kind of Object, but was HttpErrorResponse({ headers: HttpHeaders({ normalizedNames: Map( ), lazyUpdate: null, headers: Map( ) }), status: 0, statusText: 'Unknown Error', url: 'http://localhost:3000/api/reset/abc', ok: false, name: 'HttpErrorResponse', message: 'Http failure response for http://localhost:3000/api/reset/abc: 0 ', error: Object({ error: 'someError' }) }).Zymase
it starts to look like a google driven development (: @Sakthy Rupini, it is just a tiny step towards the solution. please read the error message.Farra
I thought I had to remove as ErrorEvent, but it didn't work.Zymase
Hello Sakthy, I have added an edit to the answer, as soon as @Farra will accept it, you'll get it correct. Till the time try to console thrownError as well as mockError object.Henderson
Hello @Farra , My friend has a doubt in Unit testing. Please solve this. #68335029Henderson

© 2022 - 2024 — McMap. All rights reserved.