Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are options to unit test requestAnimationFrame in Angular?

What are ways to unit test requestAnimationFrame?

requestAnimationFrame has same nature as setTimeout/setInterval have. It is also patched by zone.js like fn's like setTimeout are patched. So options which first came to my mind are

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

The results:

  1. async + whenStable : just don't work
  2. fakeAsync + tick(void) : don't work
  3. fakeAsync + flush : don't work
  4. fakeAsync + tick(number) : works (read below)
  5. setTimeout(1000) + done (jasmine) : don't work

Here is the method:

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

Here is the unit test (working unit test):

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 is some magic number like 1000/60. It is the frame size. I just found this magic number by experiments.

Also, idea which came to my mind when I was writing this question: probably, I can somehow mock ng zone and all code which passes through it will be called synchronously (I need that). I haven't tried this yet.

UPD: After some research RAF call just put a task into macrotask zone queue. How to flush this queue from the test?

So what I am missing? How to correctly unit test method with requestAnimationFrame call?

like image 506
Sharikov Vladislav Avatar asked May 10 '18 17:05

Sharikov Vladislav


1 Answers

tick(16) is correct, because requestAnimationFrame in fakeAsync is just a 16ms delay macroTask.

if you want to flush in fakeAsync, just call flush(), flush is also imported from @angular/core/testing.

like image 78
jiali passion Avatar answered Sep 25 '22 12:09

jiali passion