Angular тест активированного маршрута: настройка параметров запроса с RouterTestingModule - PullRequest
0 голосов
/ 01 мая 2020

Я обнаружил, что тестирование наблюдаемого приводит к тому, что этот тест кармы «это» запускается дважды. Первый терпит неудачу, а второй проходит.

Я использую сервис, который получает и устанавливает параметры запроса маршрутизатора. Он хранит состояние приложения по URL. Я хочу проверить, что состояние сохраняется правильно. В тесте используется RouterTestingModule. Если только я не ошибаюсь (скорее всего), мне не нужно было создавать собственный объект фиктивного маршрутизатора.

Я нашел этот пост , особенно полезный для использования done() с сервисной инъекцией.

Ниже приведены мои настройки теста.

import {inject, TestBed  } from '@angular/core/testing';

import { ArQueryService } from './ar-query.service';
import { Router, ActivatedRoute} from '@angular/router'
import { RouterTestingModule } from '@angular/router/testing';

fdescribe('ArQueryService', () => {
  let service: ArQueryService;
  let router: Router;
  let route: ActivatedRoute;
  let queryParamsDefault: Object;
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [ ArQueryService ],
      imports: [ RouterTestingModule ]
    })
    service = TestBed.inject(ArQueryService);

    router = TestBed.get(Router)
    route = TestBed.get(ActivatedRoute)

    queryParamsDefault = {
      includeRealtime: true,
      onlyBGC: false,
      onlyDeep: false,
      arHourRange: [-18, 18],
      arDate: "2010-01-01T00",
      displayGlobally: true
    }
  });

Приведенный ниже тест вводит службу и вводит done. Тест, расположенный внутри Observable, проверяет, совпадают ли ключи параметров запроса с настройками в конфигурации TestBed. Я должен включить done() после того, как все тесты были описаны, иначе тесты будут пропущены.

  it('should set url with state', done => {
    const queryParamsDefaultKeys = Object.keys(queryParamsDefault)
    inject([ArQueryService], (service: ArQueryService) => {
      service.setURL()
      route.queryParamMap.subscribe( params => {
        const equal = params.keys === queryParamsDefaultKeys 
        console.log('equal:', equal)
        console.log(queryParamsDefaultKeys, params.keys)
        if (params.keys.length == 0 ) {
          console.log('no parameters set. not testing')
        }
        else {
          console.log('here be parameter keys')
          expect(params.keys).toEqual(queryParamsDefaultKeys)
        }
        done();
      })
    })();

});

Странно то, что его запускают дважды. Первый раунд не проходит, так как у маршрутизатора нет параметров запроса. Второй делает и проходит.

То, что, вероятно, происходит, - это первый раунд при вызове setURL(). После того, как параметры установлены, второй раунд запускается и проходит.

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

Заранее спасибо!

1 Ответ

1 голос
/ 01 мая 2020

Маршрутизатор возвращает обещание при выполнении router.navigate или router.navigateByUrl и ожидает их успешного выполнения, прежде чем выполнение ваших утверждений поможет вам. Вы также можете потенциально ждать router.initialNavigation().

Но я думаю, что-то подобное может вам помочь.

import { filter } from 'rxjs/operators';
.....
it('should set url with state', done => {
    const queryParamsDefaultKeys = Object.keys(queryParamsDefault)
    // you already have a handle on ArQueryService, not sure why you're injecting it again
    inject([ArQueryService], (service: ArQueryService) => {
      service.setURL()
      route.queryParamMap.pipe(
        filter(params => !!params.keys.length), // filter out any emissions where keys is an empty array.
      ).subscribe( params => {
        expect(params.keys).toEqual(queryParamsDefaultKeys);
        done();
      })
    })();

});
...