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

Fel*_*lix 6 rxjs angular angular-test

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

}

Run Code Online (Sandbox Code Playgroud)

并且测试失败:

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

    fixture.detectChanges(); // ngOnInit

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

    expect(component.value).toBe('foo');  // <- fails here
  }));
Run Code Online (Sandbox Code Playgroud)

测试失败

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

通过考试

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

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

冲洗:

通过排空宏任务队列直到它为空来模拟 fakeAsync 区域中定时器的异步时间流逝。返回的值是已经过去的毫秒数。

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

use*_*er1 5

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

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

你可以在这里读更多关于它的内容