Шутка с угловым тестом — ошибка типа: не удается прочитать свойство ‘queryParams’ неопределенного

#javascript #angular #testing #jestjs #angular-activatedroute

#javascript #angular #тестирование #jestjs #angular-activatedroute

Вопрос:

Я видел ту же ошибку в других сообщениях, но они не сработали для меня.

У меня есть угловой компонент, где мне нужно прочитать параметр запроса из URL, например, в http://localhost:4200/sample-page?page=3 я хочу сохранить число 3 в локальной переменной компонента.

 /**
 * Set page by url parameter
 */
export const setPaginationMarkByUrlParam = (activatedRoute): number => {
  // Get page param from Url to set pagination page
  const pageParam = activatedRoute.snapshot.queryParams;
  return pageParam.page ? Number(pageParam.page) : 1;
};
 

Эта функция находится в другом файле, и я помещаю в качестве параметра activeRoute, который поступает из ngOnInit компонента, в котором я хочу получить параметр запроса.

 ngOnInit() {
    this.page = setPaginationMarkByUrlParam(this.activatedRoute);
}
 

Этот код работает отлично, но когда конвейер Jenkins запускает npx jest тесты, я получаю следующее сообщение:
TypeError: Cannot read property 'queryParams' of undefined

Моя спецификация.ts:

 beforeEach(() => {
      TestBed.configureTestingModule({
        ...,
        providers: [
          {
            provide: ActivatedRoute,
            useValue: {
              data: {
                subscribe: (fn: (value: Data) => void) =>
                  fn({
                    pagingParams: {
                      predicate: 'id',
                      reverse: false,
                      page: 0
                    }
                  })
              }
            }
          }
        ]...

it('Should call load all on init', () => {
      // GIVEN
      const headers = new HttpHeaders().append('link', 'link;link');
      spyOn(service, 'query').and.returnValue(
        of(
          new HttpResponse({
            body: [new DataSource(123)],
            headers
          })
        )
      );

      // WHEN
      comp.ngOnInit();

      // THEN
      expect(service.query).toHaveBeenCalled();
      expect(comp.dataSources[0]).toEqual(jasmine.objectContaining({ id: 123 }));
    });
 

Тест завершается с comp.ngOnInit(); ошибкой.

У меня нет никаких частных переменных, activeRoute, который используется в качестве параметра, я пробовал его с общедоступными и частными.

Рассматривая проблемы как с StackOverflow, так и с GitHub, я не смог решить эту проблему.

Большое вам спасибо!

Комментарии:

1. вы издеваетесь над активированным маршрутом? Как выглядит ваша конфигурация тестового стенда?

2. @RandyCasburn Я обновил сообщение файлом spect

Ответ №1:

Пока вы издеваетесь data , вы не издеваетесь snapshot над ActivatedRoute. Для этого у вас есть три варианта:

  1. Во-первых, вам следует рассмотреть возможность использования ActivatedRouteStub, как описано в документации. Тогда это так же просто, как: activatedRoute.setParamMap({page: 3}); установить любой параметр запроса, который вы хотите установить. Для этой опции требуется больше тестового кода
  2. Следующий вариант: это будет имитировать параметр queryParameter page в ActivatedRoute с наблюдаемым:
   provide: ActivatedRoute, useValue: {
    snapshot: of(queryParams: { page: 3 }),
  }
 
  1. Если по причине, не раскрытой в вашем вопросе, вам не нужен наблюдаемый из вашего ActivatedRoute, это будет альтернативный код:
   provide: ActivatedRoute, useValue: {
    snapshot: { queryParams: { page: 3 } }
  }
 

Наконец, в предоставленном вами коде нет вызова inject для ActivatedRoute provider и он не показывает создание тестового компонента. Поэтому, как минимум, убедитесь, что вы тоже это делаете:

Либо:

fixture = TestBed.createComponent(...);

Или:

activatedRoute = TestBed.inject(ActivatedRoute);

Если ни одно из этих предложений не решит вашу проблему, поставьте минимальный StackBlitz, который демонстрирует проблему, и мы заставим ее работать.

Ответ №2:

Как правило, для настройки / издевательства, отличного RouteOptions от того, что у вас есть ActivatedRoute с Jest, вы должны использовать:

  1. createRoutingFactory От @ngneat/spectator/jest
  2. и передайте одно или несколько RouteOptions свойств, таких как (params, queryParams, parent и т. Д.), Непосредственно в его конструкторе

Например:

 const createComponent = createRoutingFactory({
component: Component,
imports: [RouterTestingModule],
parent: {
  snapshot: {
    queryParamMap: convertToParamMap({
      //...
    }),
    paramMap: convertToParamMap({
     //...
    })
  } 
 }
});