Как проверить логику кода ngOnInit в Jasmine и Angular

Мой компонент ищет параметр в route в ngOnInit. Если параметр отсутствует, отображается ошибка. Я хочу проверить эту логику.

ngOnInit() {
    this.id = this.route.snapshot.paramMap.get("id");
    if(this.id != null) {
...    } else{
      console.log("didn't get id from the route");
      this.showDialog(...);
    }
  }

Я написал следующую спецификацию. В спецификации параметр не передается в route

 beforeEach(async() => {

    fixture = TestBed.createComponent(QuestionDetailsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

fit('should show error if question details of a question can\'t be retrieved', () => {
    spyOn(component,'showDialog');
    expect(componetn.showDialog).toHaveBeenCalled();
  });

но мой тестовый пример не проходит по причине Expected spy showDialog to have been called.

Я полагаю, проблема в том, что showDialog вызывается, когда компонент создается до вызова it.

Как проверить логику ngOnInit? Мне нужен компонент, прежде чем я смогу его протестировать (т.е. вызвать it), и я хочу протестировать логику, которая выполняется во время создания компонента.


person Manu Chadha    schedule 20.02.2019    source источник


Ответы (1)


Чтобы протестировать метод ngOnInit, вам просто нужно вызвать его:

component.ngOnInit();

И значение маршрута можно проследить:

spyOn(component.route.snapshot.paramMap,"get").and.returnValue("some_id");

Также вы можете изменить возвращаемое значение. Например:

fit("should ...", () => {
  let mock_id = null;
  spyOn(component,"showDialog");

  spyOn(component.route.snapshot.paramMap,"get").and.callFake(() => {
      return mock_id;
  });

  component.ngOnInit();
  expect(componetn.showDialog).toHaveBeenCalled();
  expect(componetn.showDialog).toHaveBeenCalledTimes(1);

  mock_id = "some_value";
  component.ngOnInit();
  expect(...).to..
  ...
  expect(componetn.showDialog).toHaveBeenCalledTimes(1);

  mock_id = "another_value";
  component.ngOnInit();
  expect(...).to..
  ...
  expect(componetn.showDialog).toHaveBeenCalledTimes(1);
});
person J. Sarabia    schedule 20.02.2019
comment
огромное спасибо. Ваше примечание о spyOn(component.route.snapshot.paramMap,"get").and.returnValue("some_id") решении проблемы также stackoverflow.com/questions/54753695/. Если вы напишете это как ответ, я с радостью его приму. - person Manu Chadha; 21.02.2019
comment
Я заметил потенциальную проблему в вашем решении. Мне пришлось сделать route общедоступным, чтобы я мог получить к нему доступ в спецификации. Есть ли альтернатива? - person Manu Chadha; 21.02.2019
comment
Нет, не нужно делать route общедоступным. Думаю, что беспокоит, так это редактор. Самый быстрый способ проигнорировать это для меня (я использую VSCode): spyOn(component["route"].snapshot.paramMap,"get").and.returnValue("some_id") - person J. Sarabia; 21.02.2019