Angular Модульное тестирование HTTP Перехватчики ошибок catchError / ErrorEvent / Error - PullRequest
0 голосов
/ 07 марта 2020

У моих HTTP-перехватчиков действительно странная проблема, с которой я действительно не могу справиться. Точнее, при изменении ErrorEvent на Error и наоборот, оно охватывает одно из условий if / else, но делает другое условие не покрытым покрытием кода. Я использую Angular 9, Jest 24 и Rx JS 6.

http-error.interceptor.ts

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<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    let errorMessage: string;

    return next.handle(request).pipe(
      catchError((err: HttpErrorResponse) => {
        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);
      })
    );
  }
}

С этой настройкой, приведенный ниже тест проходит без учета части else.

http-error.interceptor.spe c .ts

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', () => {
  let httpErrorInterceptor: HttpErrorInterceptor;
  let httpTestingController: HttpTestingController;
  let registerService: RegisterService;

  beforeEach(async () =>
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [
        RegisterService,
        {
          provide: HTTP_INTERCEPTORS,
          useClass: HttpErrorInterceptor,
          multi: true
        }
      ]
    })
  );

  beforeEach(() => {
    httpErrorInterceptor = new HttpErrorInterceptor();
    httpTestingController = TestBed.inject(HttpTestingController);
    registerService = TestBed.inject(RegisterService);
  });

  it('should catch errors when calling fake URL', async () => {
    const fakeURL = 'https://fakeapi.com';
    const fakeDataToBeSend = {
      firstName: 'Daniel',
      lastName: 'Danielecki',
      email: 'daniel.danielecki@foo.com'
    };

    jest.spyOn(window, 'alert').mockImplementation(() => {}); // 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.');
  });

Теперь в http-error.interceptor.ts Я изменяю ErrorEvent на Error и тест не пройден. Однако, если в http-error.interceptor.spe c .ts я внесу изменения, как показано ниже, тест проходит успешно. Но if не покрывается, однако else есть.

// 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.')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...