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

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

  • 异步+ when稳定
  • fakeAsync + tick(void)
  • fakeAsync +刷新
  • fakeAsync + tick(number)
  • setTimeout(1000)+完成( Jasmine )

  • 结果:
  • 异步+ whenStable:只是不起作用
  • fakeAsync + tick(void):不起作用
  • fakeAsync + flush:不起作用
  • fakeAsync + tick(number):作品(阅读下面)
  • setTimeout(1000)+完成( 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');
    }));
    

    魔数(Magic Number)。 16是一些不可思议的数字,例如1000/60。它是帧的大小。我只是通过实验发现了这个神奇的数字。

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

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

    那我想念的是什么?如何使用requestAnimationFrame调用正确地对测试方法进行单元测试?

    最佳答案

    tick(16)是正确的,因为requestAnimationFrame中的fakeAsync只是16ms delay macroTask

    如果您要刷新fakeAsync,只需调用flush(),flush也会从@angular/core/testing导入。

    09-18 02:29