主要问题是如何测试Promise完成后执行的预期操作,例如测试组件是否在收到某些远程内容后正确更新其状态.
在下面的规范中,dealWithIt()
模拟为响应完成的promise而执行的逻辑(它更新变量并触发"另一个异步事件").
it('Promises fulfilled by flushMicrotasks',fakeAsync((): void => {
let x = 1;
let y = 2;
let dealWithIt = function(p:Promise<number>) {
p.then( v => {
x = v;
Promise.resolve(v).then( v=> {y = v+1; });
});
};
let p = Promise.resolve(y);
dealWithIt(p);
flushMicrotasks();
//valid if promise handling completed
expect(x).toBe(2);
expect(y).toBe(3);
}));
it('Promises fulfilled by tick',fakeAsync((): void => {
let x = 1;
let y = 2;
let dealWithIt = function(p:Promise<number>) {
p.then( v => {
x = v;
Promise.resolve(v).then( v=> {y = v+1; });
});
};
let p = Promise.resolve(y);
dealWithIt(p);
tick();
//valid if promise handling completed
expect(x).toBe(2);
expect(y).toBe(3);
}));
Run Code Online (Sandbox Code Playgroud)
两个测试都通过了.在检查期望时,承诺得到了正确处理.
但是,它有保证吗?或者我只是幸运.
是否存在任何限制,将在fakeAsync范围内创建的所有Promise通过调用tick
或者"解雇" flushMicrotasks
.
Thi*_*ier 16
一起使用fakeAsync
和tick
/ flushMicrotasks
允许您以"同步"方式模拟异步处理.因此,保证您在then
方法中指定的回调在执行期望之前执行.
从文档:
包装要在fakeAsync区域中执行的函数:
- 通过调用flushMicrotasks()手动执行微任务,
- 定时器是同步的,tick()模拟异步的时间流逝.
如果函数末尾有任何挂起的计时器,则会抛出异常.
export tick(millis?:number):void
从angular2/src/testing/fake_async.ts中定义的angular2/testing导出(第84行)模拟fakeAsync区域中定时器的异步时间流逝.
微任务队列在此函数的最开始处以及在执行任何计时器回调之后被耗尽.
export flushMicrotasks():void
刷新任何待处理的微任务.
这是相应的plunkr:
在引擎盖下
事实上,fakeAsync
函数创建一个截取的函数的异步处理的专用区setTimeout
,clearTimeout
,setInterval
,clearInterval
而且重写scheduleMicrotask
功能.这样就fakeAsync
可以完全控制异步处理并模拟异步处理.它依赖于DelayedFunctionScheduler
Jasmine.
使用该then
方法在promise上注册回调会立即通过调用scheduleMicrotask
先前在自定义区域中定义的函数来对微任务进行排队.这样,该区域可以在何时执行promise回调.
该flushMicrotasks
函数简单地遍历已注册的微任务并同步执行它们(包括先前注册的promise的回调).它tick
做了同样的事情,但另外调用tick
了Jasmine调度程序的方法.
本文可以提供更多详细信息:
您可以查看以下源代码fakeAsync
:
归档时间: |
|
查看次数: |
9435 次 |
最近记录: |