Угловой тест с asyncScheduler и flush – почему он не работает с flush()?

Существует этот компонент Angular:

import { Component, OnDestroy, OnInit } from '@angular/core';
import { asyncScheduler, Observable, of, queueScheduler, scheduled } from 'rxjs';

@Component({
  selector: 'test-component',
  templateUrl: './test-component.component.html'
})
export class TestComponentComponent implements OnInit {
  value: string;

  constructor() { }

  ngOnInit(): void {
    const data$ = this.fetchDataScheduler();

    data$
      .subscribe(value => {
        this.value = value;
      });
  }

  private fetchDataScheduler(): Observable<string> {
    return scheduled(of('foo'), asyncScheduler);
  }

}

и тест не проходит:

it('async - test setTimeout', fakeAsync(() => {
    expect(component.value).toBeFalsy();

    fixture.detectChanges(); // ngOnInit

    expect(component.value).toBeFalsy();
    flush();

    expect(component.value).toBe('foo');  // <- fails here
  }));

неудачный тест

flush() должен сбросить все макрозадачи, но это не так. Почему? Если я использую tick(), то тест проходит.

прохождение теста

(Скриншоты выше предоставлены плагином Jest и Wallaby.)

Почему не проходит с flush(), а проходит с tick()?

сбросить:

Имитирует асинхронный ход времени для таймеров в зоне fakeAsync, очищая очередь макрозадач до тех пор, пока она не станет пустой. Возвращаемое значение — это миллисекунды времени, которое должно было пройти.

Репо находится здесь: https://stackblitz.com/github/felikf/angular-testing-examples


person Felix    schedule 08.01.2020    source источник
comment
Можете ли вы настроить stackblitz, воспроизводящий проблему? Согласно документации, tick() без аргументов является командой flush(). angular.io/guide/testing#component-with-async-service   -  person Athanasios Kataras    schedule 08.01.2020
comment
Я работаю над этим: stackblitz.com/github/felikf/angular-testing-examples вроде работает. Также можно клонировать с гитхаба.   -  person Felix    schedule 08.01.2020
comment
Отмечено как ошибка: github.com/angular/angular/issues/34742   -  person Felix    schedule 11.01.2020


Ответы (1)


asyncScheduler – это setInterval, которая является периодической macroTask, и в настоящее время API flush() сбрасывает только непериодические макрозадачи, такие как setTimeout().

Сейчас вы должны использовать tick(), чтобы заставить его работать.

Подробнее об этом можно прочитать здесь

person user1    schedule 04.12.2020
comment
См. здесь и здесь — указанная проблема принадлежит мне, Я только что забыл обновить ответ, спасибо за это. - person Felix; 07.12.2020