5

I have a component that eventually calls a bunch of HTTP services via successive switchMap to fetch data from backends.

I want to test the error handling part. The app has a global error handling (ErrorHandler) and a local error handling via catchError.

The method to test looks like this one :

 public methodUsingObservable() { this.someRequest() .pipe(catchError((error) => this.handleError(error))) .subscribe(console.log); } 

Handle error check if the error is linked to the business action, and throw it again to be processed by the global handler

handleError(error) { checkLocally(error); return throwError(error); } 

For my test, I mock someRequest with throwError to mock an issue with backend call

 it('should handle the error when one occurs', fakeAsync(() => { const service: MachinService = TestBed.get(MachinService); spyOn(service,'someRequest').and.returnValue(throwError(new Error("Failing HTTP call"))); spyOn(service,'handleError').and.callThrough(); service.methodUsingObservable(); tick(); expect(service.methodUsingObservable).toThrowError(); expect(service.handleError).toHaveBeenCalled(); })); 

However, no matter how I do spy and expect on something, Karma keeps considering the test is a failure because the subscription, as actually expected, throw an unhandled error.

I have tried with :

expect(service.methodUsingObservable).toThrowError(); expect(service.methodUsingObservable()).toThrowError(); expect(() => service.methodUsingObservable()).toThrowError(); 

But none seems to teach the system to accept the test as successful, and the test fails.

Chrome 62.0.3202 (Windows 10.0.0) MachinService should handle the error when one occurs FAILED Error: Failing HTTP call at UserContext.<anonymous> src/app/shared/services/machin.service.spec.ts:12:64) ... 

How can I mark the test as passed in these conditions?

6
  • You're actually handling error properly, but your subscription doesn't catch it eventually. try to add empty error callback to your subscription as a second parameter: .subscribe(console.log, () => {}); Commented Jan 25, 2019 at 13:46
  • if you could create a demo somewhere, i would try it myself Commented Jan 25, 2019 at 13:46
  • 1
    Also i don't think that you need fakeAsync and tick() Commented Jan 25, 2019 at 13:47
  • Not catching the error at this point is the actual behavior wanted, the core app wants to catches all exception with a global MyExceptionHandler implements ErrorHandler. Adding the error callback in the subscribe, the error does not go to the Handler. I added a catchError to intercept any recognizable business exception and display a message to the user, but then the error continues Commented Jan 25, 2019 at 14:15
  • Can you confirm you're using Jasmine version 3.* ? Commented Jan 25, 2019 at 15:58

1 Answer 1

0

Well, one way is to just remove the catchError and actually handle the error in the subscribe without even having to throw an error:

subscribe( (success)=>{}, (error)=>checkLocally(error)) ) 

This way you will be able to returnValue(throwError()) in the Spy and fakeAsync will not complain as the error will be handled.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.