3

I have Karma/Jasmine unit test for Angular interceptor intercept method which returns rxjs Observable. If there is some error in success callback unit test will appear as passed even though it should fail. Code:

method under test:

intercept(
  request: HttpRequest<any>,
  next: HttpHandler
): Observable<HttpEvent<any>> {
  ...

  return next.handle(req);
}

test:

it("some test desc", () => {
  const headers = ...
  const request = new HttpRequest('GET', '/test', '', { headers });

  const next = jasmine.createSpyObj('HttpHandler', ['handle']);
  const errorResponse = new HttpErrorResponse({
    status: 401,
    error: 'SOME_ERROR_CODE'
  });

  next.handle.and.returnValue(throwError(errorResponse));

  console.log('before');
  interceptor.intercept(request, next).subscribe(
    () => fail('Observable should resolve with error.'),
    (res: HttpErrorResponse) => {
      console.log('in');
      throw new Error('some error happened here');
      expect(res).toBe(errorResponse);
    }
  );

  console.log('after');
});

I can fix this by calling done at the end of my error callback as describe here, but I don't understand why is it necessary since my code is executed synchronously (due to the rxjs throwError using queueScheduler) which can be confirmed by the order in which logs are executed (before, in, after).

jbojcic
  • 954
  • 1
  • 11
  • 25

1 Answers1

1

It seems that RxJS catches the error thrown from the subscriber and rethrows it in the next tick.

jbojcic
  • 954
  • 1
  • 11
  • 25