Тестирование блока повторных попыток перехватчика HttpClient (не ожидается открытых запросов, найдено 1) - PullRequest
0 голосов
/ 02 апреля 2019

У меня есть простой перехватчик HttpClient, который просто повторяет неудачные запросы установленное количество раз. Сейчас я пытаюсь написать модульные тесты для него, но каким-то образом я получаю незаконченный запрос. Я пытался обернуть тест в fakeAsync или использовать done, но, похоже, это не помогло. Сейчас у меня нет идей.

Я получаю ошибку: Error: Expected no open requests, found 1: GET mock/url

Что мне не хватает?

server-error.interceptor.ts

import { Injectable } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
import { retry } from 'rxjs/operators';
import { ConfigService } from '@app/shared/services/config.service';

/**
 * Http error interceptor class
 */

@Injectable()
export class ServerErrorInterceptor implements HttpInterceptor {
  constructor(private configService: ConfigService) {}

  /**
   * Intercepts failed requests and retries set amount of times before throwing an error
   *
   * @param request  HTTP request
   * @param next  HTTP handler
   *
   * @returns Observable of Http event
   */
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).pipe(retry(this.configService.config.httpRetryCount));
  }
}

server-error.interceptor.spec.ts

import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController, TestRequest } from '@angular/common/http/testing';
import { HTTP_INTERCEPTORS, HttpClient, HttpErrorResponse } from '@angular/common/http';

import { ServerErrorInterceptor } from '@core/interceptors/server-error.interceptor';
import { ConfigService } from '@shared/services/config.service';

const mockUrl = 'mock/url';
const mockHttpRetryCount = 5;
const mockErrorText = 'Mock error!';

const mockConfigService: object = {
  config: jest.fn().mockReturnValue({
    httpRetryCount: mockHttpRetryCount
  })
};

describe('ServerErrorInterceptor', () => {
  let httpClient: HttpClient;
  let httpTestingController: HttpTestingController;
  let interceptor: ServerErrorInterceptor;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [
        ServerErrorInterceptor,
        { provide: ConfigService, useValue: mockConfigService },
        { provide: HTTP_INTERCEPTORS, useClass: ServerErrorInterceptor, multi: true }
      ]
    });

    httpClient = TestBed.get(HttpClient);
    httpTestingController = TestBed.get(HttpTestingController);
    interceptor = TestBed.get(ServerErrorInterceptor);
  });

  afterEach(() => {
    httpTestingController.verify();
  });

  it('should be created', () => {
    expect(interceptor).toBeTruthy();
  });

  it('should retry an errored request set amount of times', (): void => {
    httpClient.get(mockUrl).subscribe(
      null,
      (response: HttpErrorResponse): void => {
        expect(response.status).toEqual(500);
        expect(response.message).toEqual(`Http failure response for ${mockUrl}: 500 Server Error`);
      }
    );

    for (let i = 0; i < mockHttpRetryCount; i += 1) {
      const request: TestRequest = httpTestingController.expectOne(mockUrl);
      request.flush(mockErrorText, { status: 500, statusText: 'Server Error' });
    }
  });
});

1 Ответ

0 голосов
/ 02 апреля 2019

Я на самом деле нашел ответ сам.В моем коде было 3 отдельных ошибки:

  1. ConfigService был издевался неправильно и возвращал undefined для httpRetryCount
  2. Перехватчик не выбрасывалошибка после неудачной попытки.
  3. Цикл for в тесте должен быть запущен mockHttpRetryCount + 1, чтобы учесть все повторные попытки, а затем окончательный результат (положительный или отрицательный)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...