我正在编写一个使用requestIdleCallback调用另一个函数foo
的Angular服务。在测试中,我想确保最终调用foo
。
目前,我有一个看起来像这样的测试:
it('test', fakeAsync(() => {
// Triggers a requestIdleCallback call.
service.doSomething();
flush();
expect(otherService.foo).toHaveBeenCalled();
}));
但是当我运行此测试时,出现错误,提示从未调用otherService.foo
。我尝试使用较长的计时器将flushMicroTasks()
和tick()
的刷新替换为无效。到目前为止,唯一有效的方法是使用done()
并像这样向测试本身添加setTimeout
:
it('test', (done) => {
// Triggers a requestIdleCallback call.
service.doSomething();
setTimeout(() => {
expect(otherService.foo).toHaveBeenCalled();
done();
}, 1);
});
但是我想避免这种情况,因为它可能会导致片状。无论如何,在我做出测试断言之前,是否可以保证已刷新requestIdleCallback
?
根据this PR comment,您可以定义要由fakeAsync
区域测试的自定义macroTask。
他们说您有两个选择:
通过FakeAsyncTestSpec构造函数传递选项
const testZoneSpec = new FakeAsyncTestZoneSpec('name', false, [{source: 'HTMLCanvasElement.toBlob'}]);
有时应用程序测试代码无法访问FakeAsyncTestSpec初始化过程,因此用户也可以在之前定义全局变量加载fakeAsyncTest。
[...]
window['__zone_symbol__FakeAsyncTestMacroTask'] = [{ source: 'HTMLCanvasElement.toBlob', callbackArgs: ['testBlobData'] // the test blob data which will be passed back to callback }];
因此,在您的情况下,您将source: HTMLCanvasElement.toBlob
替换为source: window.requestIdleCallback
。