Не удалось проверить угловой http-перехватчик с кармой и жасмином - PullRequest
0 голосов
/ 26 июня 2018

Я пытаюсь проверить перехватчик http, и я не могу найти способ сделать это.

Я не знаю, почему URL не совпадает, потому что мой токен зарегистрирован в консоли, а URL запроса тоже такой же. Я протестировал все остальные мои http-сервисы, используя этот метод без перехватчика, и все прошло ...

Вот класс-перехватчик, код работает и добавляет мой токен-носитель в каждый запрос, он использует собственный класс Ionic Platform, который проверяется в тесте:

@Injectable()
export class AddHeaderInterceptor implements HttpInterceptor {

  public constructor(
      private auth: AuthService, private platform: Platform, 
      private config: ConfigurationService
  ) {}

  public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    console.debug('req', req.url);
    return Observable.fromPromise(this.platform.ready())
      .switchMap(() => Observable.fromPromise(this.auth.getToken()))
      .switchMap((tokens: TokenCacheItem[]) => {
        const baseUrl = new RegExp(this.config.getValue('baseUrl'), 'g');
        if (! req.url.match(baseUrl)) {
          return Observable.of(null);
        }
        if (tokens.length > 0) {
          return Observable.of(tokens[0].accessToken);
        }
        return Observable.throw(null);
      })
      .switchMap((token: string) => {
        console.debug('token', token);
        if (!token || token === null) {
          return next.handle(req);
        }
        const headers = req.headers
          .set('Authorization', `Bearer ${token}`)
          .append('Content-Type', 'application/json');
        const clonedRequest = req.clone({ headers });
        return next.handle(clonedRequest);
    });
  }
}

Токен зарегистрирован в консоли кармы, я также проверил URL и всегда имею хороший URL, но тест не пройден.

Вот мой макет службы аутентификации:

export class AuthServiceMock {
  getToken() {
    return Promise.resolve([
      { accessToken: 'TEST' }
    ]);
  }
}

Макет платформы:

export class PlatformMock {
  public ready(): Promise<string> {
    return Promise.resolve('READY');
  }
}

А вот и тест:

describe('AddHeaderInterceptor Service', () => {

  let http: HttpTestingController;
  let httpClient: HttpClient;
  let auth: AuthService;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [
        ConfigurationService,
        {
          provide: HTTP_INTERCEPTORS,
          useClass: AddHeaderInterceptor,
          multi: true,
        },
        { provide: Platform, useClass: PlatformMock },
        { provide: LogService, useClass: LogServiceMock },
        { provide: AuthService, useClass: AuthServiceMock }
      ],
    });
    http = TestBed.get(HttpTestingController);
    httpClient = TestBed.get(HttpClient);
    auth = TestBed.get(AuthService);
  });

  it('should add Auth header to request', () => {
    httpClient.get('/test').subscribe(res => expect(res).toBeTruthy());
    const req = http.expectOne({ method: 'GET' });
    expect(req.request.url.includes('test')).toBeTruthy();
    expect(req.request.headers.has('Authorization')).toBeTruthy();
    expect(req.request.headers.get('Authorization')).toEqual('Bearer TEST');
    req.flush({
      hello: 'world'
    });
  });
});

Я всегда получал одну и ту же ошибку:

Ошибка: ожидался один запрос на совпадение по критерию «Метод сопоставления: GET, URL: (любой)», не найден.

Похоже, что запрос никогда не запускается, я попытался создать экземпляр класса и напрямую вызвать метод перехвата, и я уже получил ту же ошибку. Я пытался шпионить метод getToken из службы аутентификации, и он никогда не вызывался. Поэтому я не знаю, почему это не удалось.

Я пытался вызвать другую службу с другим URL-адресом, но все еще получаю ту же ошибку.

Я пытался использовать абсолютные или относительные URL-адреса с http.expectOne('http://localhost:8080/test'), и он все тот же:

Ожидается один соответствующий запрос по критериям "Соответствие URL: http://localhost:8080/test", не найдено.

У кого-нибудь есть идея?

Ответы [ 2 ]

0 голосов
/ 24 августа 2018

Я столкнулся с тем же сценарием, когда начал использовать тот же шаблон fromPromise -> switchMap в моем перехватчике. Это, кажется, вызывает проблему с тестированием (хотя код, кажется, работает хорошо). Без призыва к обещанию все работает нормально.

Понятия не имею почему, но ваше решение для тестирования сработало для меня. Спасибо!

0 голосов
/ 27 июня 2018

Я нахожу решение, используя функцию karma done и создавая непосредственно объект Addheader:

fdescribe('AddHeaderInterceptor Service', () => {

  let http: HttpTestingController;
  let httpClient: HttpClient;
  let auth: AuthService;
  let logger: LogService;
  let config: ConfigurationService;
  let platform: Platform;
  let interceptor: AddHeaderInterceptor;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [
        ConfigurationService,
        {
          provide: HTTP_INTERCEPTORS,
          useClass: AddHeaderInterceptor,
          multi: true,
        },
        { provide: Platform, useClass: PlatformMocked },
        { provide: LogService, useClass: LogServiceMock },
        { provide: AuthService, useClass: AuthServiceMock }
      ],
    });
    config = TestBed.get(ConfigurationService);
    auth = TestBed.get(AuthService);
    logger = TestBed.get(LogService);
    platform = TestBed.get(Platform);
    httpClient = TestBed.get(HttpClient);
    http = TestBed.get(HttpTestingController);
    interceptor = new AddHeaderInterceptor(logger, auth, platform, config);
  });

  fit('should add header to request', (done) => {
    expect((interceptor as any) instanceof AddHeaderInterceptor).toBeTruthy();
    const next: any = {
      handle: (request: HttpRequest<any>) => {
        expect(request.headers.has('Authorization')).toBeTruthy();
        expect(request.headers.get('Authorization')).toEqual('Bearer TESTO');
        return Observable.of({ hello: 'world' });
      }
    };
    const req = new HttpRequest<any>('GET', config.getValue('baseUrl') + 'test');
    interceptor.intercept(req, next).subscribe(obj => done());
  });

});
...