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
The results:
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?
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With