title: Angular Unit Testing HTTP Error Interceptors catchError/ErrorEvent/Error
body: <p>My HTTP Interceptors have really weird problem, which I really cannot manage. More precisely, when changing <code>ErrorEvent</code> to <code>Error</code> and vice versa it covers one of the if/else conditions but making the other one not covered in code coverage. I'm using Angular 9, Jest 24 and RxJS 6.</p>
  
  <p><strong>http-error.interceptor.ts</strong></p>
  
  <pre><code>import {
    HttpErrorResponse,
    HttpEvent,
    HttpHandler,
    HttpInterceptor,
    HttpRequest
  } from '@angular/common/http';
  import { catchError } from 'rxjs/operators';
  import { Injectable } from '@angular/core';
  import { Observable, throwError } from 'rxjs';
  
  @Injectable()
  export class HttpErrorInterceptor implements HttpInterceptor {
    intercept(
      request: HttpRequest&lt;any&gt;,
      next: HttpHandler
    ): Observable&lt;HttpEvent&lt;any&gt;&gt; {
      let errorMessage: string;
  
      return next.handle(request).pipe(
        catchError((err: HttpErrorResponse) =&gt; {
          if (err.error instanceof ErrorEvent) {
            // Client-side error.
            errorMessage = `An error occurred: ${err.error.message}`;
            alert('Network error.');
          } else {
            // Server-side error.
            alert('Server unavailable.');
            errorMessage = `Backend returned code ${err.status}, body was: ${err.error}`;
          }
  
          return throwError(errorMessage);
        })
      );
    }
  }
  </code></pre>
  
  <p>With this setup, the test below is passing without covering the <code>else</code> part.</p>
  
  <p><strong>http-error.interceptor.spec.ts</strong></p>
  
  <pre><code>import { TestBed } from '@angular/core/testing';
  import { HttpErrorInterceptor } from './http-error.interceptor';
  import {
    HttpClientTestingModule,
    HttpTestingController
  } from '@angular/common/http/testing';
  import { HTTP_INTERCEPTORS } from '@angular/common/http';
  import { RegisterService } from './register.service';
  
  describe('HttpErrorInterceptor', () =&gt; {
    let httpErrorInterceptor: HttpErrorInterceptor;
    let httpTestingController: HttpTestingController;
    let registerService: RegisterService;
  
    beforeEach(async () =&gt;
      TestBed.configureTestingModule({
        imports: [HttpClientTestingModule],
        providers: [
          RegisterService,
          {
            provide: HTTP_INTERCEPTORS,
            useClass: HttpErrorInterceptor,
            multi: true
          }
        ]
      })
    );
  
    beforeEach(() =&gt; {
      httpErrorInterceptor = new HttpErrorInterceptor();
      httpTestingController = TestBed.inject(HttpTestingController);
      registerService = TestBed.inject(RegisterService);
    });
  
    it('should catch errors when calling fake URL', async () =&gt; {
      const fakeURL = 'https://fakeapi.com';
      const fakeDataToBeSend = {
        firstName: 'Daniel',
        lastName: 'Danielecki',
        email: 'daniel.danielecki@foo.com'
      };
  
      jest.spyOn(window, 'alert').mockImplementation(() =&gt; {}); // Note: window.alert = jest.fn() works too, but it contaminates other tests, therefore try to avoid it.
  
      // Make an HTTP POST request
      await registerService.registerUser(fakeDataToBeSend, fakeURL).subscribe(); // https://github.com/angular/angular/issues/18345 ????
  
      httpTestingController
        .expectOne(fakeURL)
        .error(new ErrorEvent('Network error.')); //Error type instance can't be passed.
  
      expect(window.alert).toHaveBeenCalledWith('Network error.');
  
      // httpTestingController
      //   .expectOne(fakeURL)
      //   .error(new ErrorEvent('Server unavailable.')); //Error type instance can't be passed.
  
      // expect(window.alert).toHaveBeenCalledWith('Server unavailable.');
    });
  </code></pre>
  
  <p>Now, in the <strong>http-error.interceptor.ts</strong> I'm changing <code>ErrorEvent</code> to <code>Error</code> and the test will fail. However, if in the <strong>http-error.interceptor.spec.ts</strong> I'll do the changes like below the test is passing. But, the <code>if</code> is not covered, however <code>else</code> is.</p>
  
  <pre><code>// httpTestingController
  //   .expectOne(fakeURL)
  //   .error(new ErrorEvent('Network error.')); //Error type instance can't be passed.
  
  // expect(window.alert).toHaveBeenCalledWith('Network error.');
  
  httpTestingController
    .expectOne(fakeURL)
    .error(new ErrorEvent('Server unavailable.')); //Error type instance can't be passed.
  
  expect(window.alert).toHaveBeenCalledWith('Server unavailable.')
  </code></pre>