I'm writing an Angular service that uses requestIdleCallback to call another function, foo
. In my test, I want to make sure that foo
is being called eventually.
Currently I have a test that looks like this:
it('test', fakeAsync(() => {
// Triggers a requestIdleCallback call.
service.doSomething();
flush();
expect(otherService.foo).toHaveBeenCalled();
}));
But when I run this test, I get an error saying that otherService.foo
was never called. I've tried replacing the flush with flushMicroTasks()
and tick()
with a long timer to no avail. The only thing that has worked so far was to use done()
and add a setTimeout
to the test itself like this:
it('test', (done) => {
// Triggers a requestIdleCallback call.
service.doSomething();
setTimeout(() => {
expect(otherService.foo).toHaveBeenCalled();
done();
}, 1);
});
But I would like to avoid this because it could cause some flakiness. Is there anyway to guarantee that requestIdleCallback
was flushed before I make my test assertion?
According to this PR comment, you can define custom macroTasks to be tested by
fakeAsync
zone.They say you have two options:
So in your case you'd replace
source: HTMLCanvasElement.toBlob
withsource: window.requestIdleCallback
.