Как следить за методом, вызываемым в подписке внутри ngOnInit в спецификации теста Angular?

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

component.ts

//Value I want to test
value;

//This is the property I need to check
get isThisTrue() {
    return this.externalService.isTrue();
}

ngOnInit() {
this.otherService.getSomething().subscribe(res => {
  this.method();
   })
}

method() {
  if(this.isThisTrue) {
   this.value = 1;
  } else {
     this.value = 2;
}

component.spec.ts

//That is my failing test.
it('should be 2', inject([ExternalService], (service) => {
  spyOn(service, 'isTrue').and.returnValue(false);
  component.ngOnInit();
  fixture.detectChanges();
  expect(value).toBe(2);
}))

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


person Ruvalter    schedule 21.01.2019    source источник
comment
Приведите минимальный воспроизводимый пример.   -  person jonrsharpe    schedule 22.01.2019
comment
Я просто хочу следить за вызовом метода и возвращать значение внутри подписки внутри ngOnInit.   -  person Ruvalter    schedule 22.01.2019
comment
Вам нужно выполнить его в асинхронном режиме и вызвать done или использовать любой другой метод для тестов, где у вас есть асинхронное поведение.   -  person Nanotron    schedule 22.01.2019
comment
Я пробовал этот @Nanotron, но проблема в том, что метод вызывается внутри подписки. Обычно асинхронный подход помогает, когда вы хотите подождать, пока не получите выполнение, чтобы с ним можно было работать. Дело в том, что меня не волнует, на что подписывается, меня волнует только метод, который был вызван внутри. Шпион не работает, даже когда я использую асинхронные подходы   -  person Ruvalter    schedule 22.01.2019
comment
Тогда вам, вероятно, нужно будет издеваться / шпионить за этим. Например, если в этой подписке использовалось http req, вам нужно было бы имитировать это. Ваш метод никогда не будет вызван. Вы его вообще отлаживали? Поместите точку останова внутри ngOnit и посмотрите, что произойдет   -  person Nanotron    schedule 22.01.2019


Ответы (1)


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

В моем случае проблема заключалась в том, что компонент создавался в методе beforeEach ().

beforeEach(() => {
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    fixture.detectChanges(); 
});

Таким образом, его ngOnInit () также вызывался непосредственно перед тем, как шпионский метод мог вернуть фиктивные данные.

Я переместил код из метода beforeEach () в функцию createComponent ()

function createComponent(){
    fixture = TestBed.createComponent(MyComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
 }

и вызвал эту функцию из тестовой спецификации после возврата фиктивных данных с помощью spyOn.

it('should create component with 2 rows', async () => {
    const expectedData: string[] = ['row 1', 'row 2'];
    myServiceSpy.getData.and.returnValue(expectedData));

    createComponent();

    expect(component).toBeTruthy();
    fixture.whenStable().then(() => {
        expect(myServiceSpy.getData).toHaveBeenCalled();
        expect(component.data.length).toEqual(2);
    });
});

Now, the component is getting the mock data as expected
person PradnyaK    schedule 07.07.2020
comment
Этот ответ помог мне разобраться в моей ситуации: я пытался шпионить за методом компонента, который был вызван в ngOnInit. Я использую ту же настройку, при этом компонент создается в beforeEach, поэтому метод был вызван до того, как у меня появилась возможность разместить на нем шпиона. Я также использую ComponentFixtureAutoDetect, поэтому, когда я переместил создание компонента в тест (чтобы обойти обнаружение автоматического изменения), он все еще не работал, потому что обнаружение изменений все еще запускалось при создании компонента. Мне пришлось прокомментировать CFAD и выполнить обнаружение изменений вручную, чтобы он наконец заработал. - person RepentAndBelieveTheGospel; 12.02.2021