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
- async + whenStable
- fakeAsync + tick(void)
- fakeAsync + flush
- fakeAsync + tick(number)
- setTimeout(1000) + done (jasmine)
The results:
- async + whenStable : just don't work
- fakeAsync + tick(void) : don't work
- fakeAsync + flush : don't work
- fakeAsync + tick(number) : works (read below)
- 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?