在 Angular 中单元测试 requestAnimationFrame 有哪些选项?

Sha*_*lav 8 javascript unit-testing zone.js angular ngzone

对 requestAnimationFrame 进行单元测试的方法有哪些?

requestAnimationFrame 与 setTimeout/setInterval 具有相同的性质。它也由 zone.js 修补,就像 fn 的 setTimeout 一样被修补。所以我首先想到的选项是

  1. 异步 + 当稳定
  2. fakeAsync + 滴答(无效)
  3. 假异步 + 刷新
  4. fakeAsync + 滴答声(数字)
  5. setTimeout(1000) + 完成(茉莉花)

结果:

  1. async + whenStable :就是不工作
  2. fakeAsync + tick(void) :不起作用
  3. fakeAsync + 刷新:不起作用
  4. fakeAsync + tick(number) :有效(阅读下文)
  5. setTimeout(1000) + done (jasmine) :不工作

这是方法:

 reqAnimFrame() {
   requestAnimationFrame(() => {
     console.log('log stuff');
     this.title = 'req frame title';
   });
 }
Run Code Online (Sandbox Code Playgroud)

这是单元测试(工作单元测试):

it('fakeAsync', fakeAsync(function () {
  const fixture = TestBed.createComponent(AppComponent);
  const app: AppComponent = fixture.debugElement.componentInstance;

  fixture.detectChanges();

  app.reqAnimFrame();

  tick(16);

  expect(app.title).toBe('req frame title');
}));
Run Code Online (Sandbox Code Playgroud)

神奇的数字。16 是一些神奇的数字,例如 1000/60。它是框架大小。我刚刚通过实验发现了这个神奇的数字。

另外,我在写这个问题时想到的想法:可能,我可以以某种方式模拟 ng zone 并且所有通过它的代码都将被同步调用(我需要那个)。我还没有尝试过这个。

UPD:经过一些研究 RAF 调用后,只需将任务放入宏任务区队列。如何从测试中刷新这个队列?

那么我缺少什么?如何通过requestAnimationFrame调用正确地进行单元测试方法?

jia*_*ion 8

tick(16)是正确的,因为requestAnimationFrameinfakeAsync只是一个16ms delay macroTask.

如果你想flush进去fakeAsync,直接调用即可flush(),flush也是从 导入的@angular/core/testing