使用asyncScheduler和flush进行角度测试-为什么使用flush()失败?

时间:2020-01-08 15:49:39

标签: angular rxjs angular-testing

有这个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
  }));

failing test

flush()应该刷新所有宏任务,但不刷新。为什么? 如果我使用tick(),则测试通过。

passing test

(以上截图由Jest和Wallaby插件提供。)

为什么不通过flush(),而是通过tick()

flush

通过清空宏任务队列直到其为空,为fakeAsync区域中的计时器模拟异步时间流逝。返回的值是本应经过的毫秒数。

回购在这里:https://stackblitz.com/github/felikf/angular-testing-examples

1 个答案:

答案 0 :(得分:1)

asyncScheduler 是一个setInterval,它是一个周期性的 macroTask ,目前, flush()API仅刷新非周期性的MacroTask,例如setTimeout ()

现在您应该使用 tick()使其正常工作。

您可以详细了解here