Angular 13 Как выполнить модульное тестирование метода перехватчика catchError

Я работаю над существующим проектом Angular, и у меня есть следующий перехватчик с обработкой ошибок. это код:

public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
   
    const sendAccessToken = this.moduleConfig.resourceServer.sendAccessToken;
    
    if (sendAccessToken) {
      const token = this.authStorage.getItem('access_token');
      const header = 'Bearer ' + token;

      const headers = req.headers.set('Authorization', header);

      req = req.clone({ headers });
    }
    
    return next.handle(req).pipe(
      catchError(err => {
        let errorMessage: string;
        if (err instanceof HttpErrorResponse) {

          switch (err.status) {
            
            case 401: {
              errorMessage = 'Autorisation required.';
              break;
            }

            default: {
              const erreurText = err.error.messages[0].message
              break;
            }
          }
        }

        this.toastr.error(errorMessage);
        const error = err.error;

        return error;

      }),
    ) as any;
  }

и это мой тест, в котором я хочу вызвать catcherror, но я не знаю, как я могу это сделать:

  it('#should handle incorrect url', () => {
    const requestMock = new HttpRequest('GET', '/wrongtest');
    interceptor.intercept(requestMock, next).subscribe(() => {
      expect(requestMock.headers.has('Authorization')).toEqual(false);
    });
  });

может ли кто-нибудь помочь мне, как я могу вызвать ошибку в моем HttpRequest.

заранее спасибо.

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
0
23
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Предполагая, что вы используете жасмин для тестирования:

  1. Введите все ваши тестовые зависимости:
// Necessary to inject the right HTTP interceptor
const interceptorOf = <T>(type: Type<T>) =>
  TestBed
    .inject(HTTP_INTERCEPTORS)
    .find(interceptor => interceptor instanceof type) as unknown as T

describe('...', () => {
  let httpClient: HttpClient
  let httpMock: HttpTestingController
  let interceptor: ErrorInterceptor

  beforeEach(async () =>
    await TestBed.configureTestingModule({
      imports: [
        // Load all your interceptor's dependencies
        HttpClientTestingModule,
      ],
      providers: [
        {
          provide: HTTP_INTERCEPTORS,
          deps: [], // Fill with your interceptor's dependencies 
          useClass: ErrorInterceptor,
          multi: true
        },
      ],
    }).compileComponents()
    httpMock = TestBed.inject(HttpTestingController)
    httpClient = TestBed.inject(HttpClient)
    interceptor = interceptorOf(ErrorInterceptor)
  })
})
  1. Вызовите обычную конечную точку и смоделируйте ответ:
it('should do something', async () =>{
    const observable$ = httpClient.get(testUrl)
    const serviceUnavailable = new HttpErrorResponse({
      status: 503,
      statusText: 'Service Unavailable',
      url: testUrl
    })

    const httpReqPromise = firstValueFrom(observable$)
    httpMock.expectOne(testUrl).flush('error', serviceUnavailable)
    
    try {
      await httpReqPromise
      fail('It should have not succeeded')
    } catch(error) {
       expect(error instanceof HttpErrorResponse).toBeTrue()
       expect(error.status).toBe(503)
    }
})

Примечание 1: Ваше использование трубы catchError недействительно; вы не должны возвращать ошибку, а наблюдаемый объект, который будет использоваться вместо того, который потерпел крах.

catchError(err => {
  ...
  const error = err.error;
  return of(error);
})

Заметка 2: Если вы сделаете то, что я сделал во фрагменте выше, ваша ошибка будет распространена на «следующий» обратный вызов, который должен разрешить следующее обещание как успешное.

it('should do something', async () =>{
    const observable$ = httpClient.get(testUrl)
    const serviceUnavailable = new HttpErrorResponse({
      status: 503,
      statusText: 'Service Unavailable',
      url: testUrl
    })

    const httpReqPromise = firstValueFrom(observable$)
    httpMock.expectOne(testUrl).flush('error', serviceUnavailable)
    
    try {
      const error = await httpReqPromise
      expect(error instanceof HttpErrorResponse).toBeTrue()
      expect(error.status).toBe(503)
    } catch(__) {
      fail('It should have not thrown')
    }
})

спасибо за ответ, я попробовал ваш It () с testUrl = '/ test' и получил ошибку: ожидался один соответствующий запрос для критерия «Соответствие URL: / test», не найдено.

James 11.05.2022 11:36

Вы, вероятно, пропустили subscribe на observable$ или преобразование в обещание, чтобы HTTP-вызов вступил в силу.

Some random IT boy 11.05.2022 11:38

он отлично работает, когда я подписываюсь на наблюдаемые $. у вас есть идеи, как я могу ожидать, что error.status будет соответствовать 503 в моем тесте? спасибо

James 11.05.2022 11:54

Я обновил свой ответ полным примером вместе с некоторыми другими примечаниями.

Some random IT boy 11.05.2022 13:42

Другие вопросы по теме