nip*_*777 17 javascript unit-testing asynchronous jasmine angular
我试图从Angular 2中的模拟后端获得单元测试的结果.目前,我们使用fakeAsync
超时来模拟时间的流逝.
目前的工作单位测试
it('timeout (fakeAsync/tick)', fakeAsync(() => {
counter.getTimeout();
tick(3000); //manually specify the waiting time
}));
Run Code Online (Sandbox Code Playgroud)
但是,这意味着我们仅限于手动定义的超时.不是在异步任务完成时.我要做的是tick()
等待任务完成后再继续测试.
这似乎没有按预期工作.
阅读fakeAsync
和tick
答案在这里解释说:
tick()模拟异步时间的流逝.
我设置了一个模拟这个场景的plnkr示例.
在这里,我们调用getTimeout()
调用具有超时的内部异步任务的方法.在测试中,我们尝试包装它并tick()
在调用getTimeout()
方法后调用.
counter.ts
getTimeout() {
setTimeout(() => {
console.log('timeout')
},3000)
}
Run Code Online (Sandbox Code Playgroud)
counter.specs.ts
it('timeout (fakeAsync/tick)', fakeAsync(() => {
counter.getTimeout();
tick();
}));
Run Code Online (Sandbox Code Playgroud)
但是,单元测试失败,错误"错误:1个计时器仍在队列中".
是否可以使用tick()
这种方式等待超时功能?或者我可以使用另一种方法吗?
小智 21
尝试将以下函数调用的一个或组合添加到测试的末尾:
flush();
flushMicrotasks();
discardPeriodicTasks();
Run Code Online (Sandbox Code Playgroud)
flush
(带有可选的 maxTurns 参数)也会刷新宏任务。(Angular 测试教程中没有提到这个功能。)flushMicrotasks
刷新微任务队列。discardPeriodicTasks
取消“仍在队列中的周期计时器”。队列中的计时器并不一定意味着您的代码存在问题。例如,观察当前时间的组件可能会引入这样的计时器。如果您使用来自外部库的此类组件,您可能还会考虑存根它们而不是“追逐计时器”。
如需进一步了解,你可以看看的JavaScript代码fakeAsync
的功能zone-testing.js
。
nep*_*hiw 14
的目的fakeAsync
是在您的规范内控制时间。tick
它将不会等待任何时间,因为它是用于模拟时间流逝的同步功能。如果您要等到异步功能完成,则需要使用async
和whenStable
,但是,在您的示例中,规范将需要3秒钟才能通过,因此我不建议这样做。
为什么原因counter.spec.ts失败是你唯一的模拟0秒(通常用于表示该事件循环的下一个刻度)的通道。因此,当规范完成时,仍然有模拟计时器处于活动状态,这会使整个规范失效。通知您模拟了超时,并且未处理,它实际上在正常工作。
基本上,我认为你正试图利用fakeAsync
并tick
为他们并不打算使用方式。如果您需要按照建议的方法测试超时,最简单的方法就是setTimeout
自己模拟函数,以便无论使用什么时间,都可以调用该方法。
编辑 我遇到一个相关的问题,我想清除计时器,由于它不是受测试的部件,所以我不在乎它花了多长时间。我试过了:
tick(Infinity);
Run Code Online (Sandbox Code Playgroud)
哪个可行,但超级hacky。我最终去了
discardPeriodicTasks();
Run Code Online (Sandbox Code Playgroud)
而且我所有的计时器都清除了。
在每个测试的末尾添加:
fixture.destroy();
flush();
Run Code Online (Sandbox Code Playgroud)
我通常在单元测试中使用lushMicrotasks 方法来与我的服务一起使用。我读过,tick() 与flushMicrotasks 非常相似,但也调用jasmine tick() 方法。
归档时间: |
|
查看次数: |
15336 次 |
最近记录: |