Как издеваться над route.snapshot.params?

В моем компоненте Angular 4 у меня есть что-то вроде:

constructor(private route: ActivatedRoute) {
}

ngOnInit() {
  this.myId = this.route.snapshot.params['myId'];
}

И я пытаюсь создать макет, который должен выглядеть следующим образом:

class MockActivatedRoute extends ActivatedRoute {
  public params = Observable.of({ myId: 123 });
}    

Мой тест не работает с:

TypeError: Не удается прочитать параметры свойства undefined.

Как я могу издеваться над этим? Я неправильно понял правильное использование ActivatedRoute и должен ли лучше использовать router.subscribe в моем компоненте? Я видел несколько сложных примеров, когда люди издевались над самим снэпшотом, но для меня это выглядит чересчур сложным.


Сам тест довольно прост:

describe('ngOnInit', () => {
it('should set up initial state properly',
  () => {
  const component = TestBed.createComponent(MyComponent).componentInstance;
    component.ngOnInit();
    expect(component.myId).toEqual('123');
  });
});

Если я просто изменю тестируемый метод на что-то вроде следующего - тест работает:

ngOnInit() {
    //this.myId = this.route.snapshot.params['myId'];
    this.route.params.subscribe(params => {
    this.myId = params['myId'];
    });
}

Очевидно, мне нужно издеваться над активированным снимком, но есть ли лучший подход?


person and85    schedule 19.10.2017    source источник
comment
Я также пытался сделать что-то вроде const fakeRoutes: Routes = [{path: 'info', data: { catalogId: '123' }, component: StatusComponent},], а затем RouterTestingModule.withRoutes(fakeRoutes). Не уверен, что этот синтаксис поддерживается.   -  person and85    schedule 19.10.2017
comment
Вы пытаетесь использовать это в модульном тестировании? Если да, то можете ли вы опубликовать этот код   -  person LLai    schedule 19.10.2017
comment
Вы получаете параметры undefined, потому что ваш макет издевается над наблюдаемыми параметрами this.route.params (возвращает наблюдаемое) вместо снимка this.route.snapshot.params (возвращает объект параметров)   -  person LLai    schedule 19.10.2017
comment
Да спасибо. snapshot также использует параметры, поэтому я подумал, что он должен быть достаточно умным, чтобы понять, что я издевался над параметрами. Это означает, что если бы я хотел издеваться над моментальным снимком и параметрами, мне нужно было бы дважды скопировать и вставить параметры. Во всяком случае, вчера мне удалось решить эту проблему, спасибо за помощь.   -  person and85    schedule 20.10.2017


Ответы (2)


Хорошо, я нашел, как просто имитировать моментальный снимок ActivatedRoute. Что-то вроде этого работает для меня:

providers: [MyComponent, {
  provide: ActivatedRoute,
  useValue: {snapshot: {params: {'myId': '123'}}}
}

Спасибо :)

person and85    schedule 19.10.2017

Если вместо этого используется route.snapshot.paramMap.get('uuid'):

import { ActivatedRoute, convertToParamMap } from '@angular/router';

{
    provide: ActivatedRoute, useValue:
        { snapshot: { paramMap: convertToParamMap( { 'uuid': '99-88-77' } ) } }
}
person Simon    schedule 19.10.2018
comment
Это именно то, что мне было нужно, спасибо! В противном случае возникает ошибка this.route.snapshot.paramMap.get is not a function. - person michaeak; 24.04.2020
comment
Большое спасибо, ваш ответ спас мой день. - person Alaa El-din Ahmed Muhammad; 14.03.2021