在Angular中,如何对requestAnimationFrame进行单元测试?有哪些选项?

12

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

requestAnimationFrame与setTimeout/setInterval具有相同的性质,也像setTimeout这样的函数一样被zone.js打补丁。所以我首先想到的选项是:

  1. async + whenStable
  2. fakeAsync + tick(void)
  3. fakeAsync + flush
  4. fakeAsync + tick(number)
  5. setTimeout(1000) + done (jasmine)

结果如下:

  1. async + whenStable:根本不起作用
  2. fakeAsync + tick(void):不起作用
  3. fakeAsync + flush:不起作用
  4. fakeAsync + tick(number):起作用(详见下文)
  5. setTimeout(1000) + done (jasmine):不起作用

以下是该方法:

 reqAnimFrame() {
   requestAnimationFrame(() => {
     console.log('log stuff');
     this.title = 'req frame title';
   });
 }

这是一个单元测试(有效的单元测试):

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');
}));

魔数。16就像1000/60一样是一种神奇的数字。这是帧大小。我通过实验找到了这个神奇的数字。

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

更新:经过一些研究,RAF调用只是将任务放入宏任务区队列中。如何从测试中清空此队列?

那么我错过了什么? 如何正确地对具有requestAnimationFrame调用的方法进行单元测试?


1
这完全不是基于个人观点。我在询问测试特定内容的方法。 - Sharikov Vladislav
https://github.com/angular/angular/issues/12372。嘿呀。 - Sharikov Vladislav
1个回答

8

tick(16) 是正确的,因为在 fakeAsync 中的 requestAnimationFrame 只是一个 16毫秒的延迟宏任务

如果您想在 fakeAsync 中刷新,请调用 flush()flush 也是从 @angular/core/testing 导入的。


我尝试过这个,但它没有起作用。我在我的问题中已经说过了。顺便说一下,我就是来自Github的那个sharikovvladislav :) 我们在问题中有过一些交流。 - Sharikov Vladislav
好的,你能在 GitHub 上提供一个可复现的仓库吗?如果是 bug 的话,我会修复它。 - jiali passion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接