主要问题是如何测试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);
}));
两个测试都通过了。在检查期望时,承诺得到了正确处理。
但是,是否有保障?或者我只是幸运。
是否存在任何限制,通过调用tick
或flushMicrotasks
,可以“触发”在fakeAsync范围内创建的所有Promise。
答案 0 :(得分:16)
同时使用fakeAsync
和tick
/ flushMicrotasks
可以让您以“同步”方式模拟异步处理。因此,保证您在then
方法中指定的回调在执行期望之前执行。
来自文档:
包装要在fakeAsync区域中执行的函数:
通过调用flushMicrotasks(),手动执行
- 微任务
- 计时器是同步的,tick()模拟异步的时间流逝。
如果函数末尾有任何挂起的计时器,则会抛出异常。
导出刻度(毫秒?:数字):无效
从angular2 / src / testing / fake_async.ts中定义的angular2 / testing导出(第84行) 模拟fakeAsync区域中定时器的异步时间流逝。
微任务队列在此函数开始时以及执行任何计时器回调后都会耗尽。
导出flushMicrotasks():void
刷新任何待处理的微任务。
这是相应的plunkr:
引擎盖
实际上fakeAsync
函数创建了一个专用区域,用于拦截函数setTimeout
,clearTimeout
,setInterval
,clearInterval
的异步处理,但也覆盖{ {1}}功能。这样scheduleMicrotask
就可以完全控制异步处理并模拟异步处理。它依赖于Jasmine的fakeAsync
。
使用DelayedFunctionScheduler
方法在promise上注册回调会立即通过调用先前在自定义区域中定义的then
函数对微任务进行排队。这样,该区域可以在何时执行promise回调。
scheduleMicrotask
函数简单地迭代已注册的微任务并同步执行它们(包括先前注册的promise的回调)。 flushMicrotasks
执行相同的操作,但另外调用了Jasmine调度程序的tick
方法。
本文可以提供更多详细信息:
您可以查看tick
的源代码:
答案 1 :(得分:1)
所以是的,正如蒂埃里在答案中解释的那样,fakeAsync允许同步测试处理承诺背后的业务逻辑。
我只是想补充一点,对于fakeAsync的测试甚至还有与promise有关的规范:
describe('Promise', () => {
it('should run asynchronous code', fakeAsync(() => {
...
it('should run chained thens', fakeAsync(() => {
...
it('should run Promise created in Promise', fakeAsync(() => {
我在https://github.com/angular/angular/blob/master/packages/core/test/fake_async_spec.ts
找到了这些测试