Angular 2 fakeAsync 在使用tick()的函数中等待超时?

Angular 2 fakeAsync waiting for timeout in a function using tick()?(Angular 2 fakeAsync 在使用tick()的函数中等待超时?)
本文介绍了Angular 2 fakeAsync 在使用tick()的函数中等待超时?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我正在尝试从 Angular 2 中的模拟后端获取结果以进行单元测试.目前,我们正在使用带有超时的 fakeAsync 来模拟时间的流逝.

I'm trying to get the results from a mock backend in Angular 2 for unit testing. Currently, we are using fakeAsync with a timeout to simulate the passing of time.

当前工作单元测试

it('timeout (fakeAsync/tick)', fakeAsync(() => {
    counter.getTimeout();
    tick(3000); //manually specify the waiting time
}));

但是,这意味着我们仅限于手动定义的超时.不是在异步任务完成时.我想做的是让 tick() 等到任务完成后再继续测试.

But, this means that we are limited to a manually defined timeout. Not when the async task is completed. What I'm trying to do is getting tick() to wait until the task is completed before continuing with the test.

这似乎没有按预期工作.

This does not seem to work as intended.

阅读 fakeAsynctick 答案这里 解释说:

Reading up on the fakeAsync and tick the answer here explains that:

tick() 模拟时间的异步流逝.

tick() simulates the asynchronous passage of time.

我设置了一个 plnkr 示例来模拟这种情况.

I set up a plnkr example simulating this scenario.

在这里,我们调用 getTimeout() 方法,该方法调用具有超时的内部异步任务.在测试中,我们尝试包装它并在调用 getTimeout() 方法后调用 tick().

Here, we call the getTimeout() method which calls an internal async task that has a timeout. In the test, we try wrapping it and calling tick() after calling the getTimeout() method.

counter.ts

getTimeout() {
  setTimeout(() => {
    console.log('timeout')
  },3000)
}

counter.specs.ts

it('timeout (fakeAsync/tick)', fakeAsync(() => {
    counter.getTimeout();
    tick();
}));

但是,单元测试失败并出现错误错误:1 个计时器仍在队列中."

But, the unit test fails with the error "Error: 1 timer(s) still in the queue."

角度回购中的问题是否与此有关?

Does the issue here in the angular repo have anything to do with this?

是否可以这样使用tick()来等待超时函数?还是我可以使用另一种方法?

Is it possible to use tick() this way to wait for a timeout function? Or is there another approach that I can use?

推荐答案

fakeAsync 的目的是在你的规范内控制时间.tick 不会等待任何时间,因为它是用于模拟时间流逝的同步函数.如果您想等到异步功能完成,您将需要使用 asyncwhenStable,但是,在您的示例中,规范需要 3 秒才能完成通过,所以我不建议这样做.

The purpose of fakeAsync is to control time within your spec. tick will not wait for any time as it is a synchronous function used to simulate the passage of time. If you want to wait until the asynchronous function is complete, you are going to need to use async and whenStable, however, in your example, the spec will take 3 seconds to pass so I wouldn't advise this.

counter.spec.ts 失败的原因是您只模拟了 0 秒的过去(通常用于表示事件循环的下一个滴答声).因此,当规范完成时,仍然有模拟的计时器处于活动状态,这使整个规范失败.通过通知您超时已被模拟并且未处理,它实际上可以正常工作.

The reason why the counter.spec.ts is failing is that you have only simulated the passage of 0 seconds (typically used to represent the next tick of the event loop). So when the spec completes, there are still mocked timers active and that fails the whole spec. It is actually working properly by informing you that a timeout has been mocked an is unhandled.

基本上,我认为您正在尝试以不打算使用它们的方式使用 fakeAsynctick.如果您需要按照您建议的方式测试超时,最简单的方法是自己模拟 setTimeout 函数,这样,无论使用多少时间,您都可以调用该方法.

Basically, I think you are attempting to use fakeAsync and tick in ways for which they were not intended to be used. If you need to test a timeout the way that you have proposed, the simplest way would be to mock the setTimeout function yourself so that, regardless of the time used, you can just call the method.

已编辑我遇到了一个相关的问题,我想清除计时器,因为它不是被测试的部分,所以我不在乎花了多长时间.我试过了:

EDITED I ran into a related issue where I wanted to clear the timers, and since it was not the part under test, I didn't care how long it took. I tried:

tick(Infinity);

这很有效,但是超级hacky.我最终选择了

Which worked, but was super hacky. I ended up going with

discardPeriodicTasks();

我所有的计时器都被清除了.

And all of my timers were cleared.

这篇关于Angular 2 fakeAsync 在使用tick()的函数中等待超时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

Drag amp; Drop with Protractor by Repeater(拖动amp;通过中继器使用量角器掉落)
Getting the position of the element in a list when it#39;s drag/dropped (ui.sortable)(拖放时获取元素在列表中的位置(ui.sortable))
Detecting HTML5 Drag And Drop support in javascript(在 javascript 中检测 HTML5 拖放支持)
HTML5 drop event doesn#39;t work unless dragover is handled(除非处理了拖动,否则 HTML5 放置事件不起作用)
How to use jQuery#39;s drop event to upload files dragged from the desktop?(如何使用 jQuery 的 drop 事件上传从桌面拖动的文件?)
Drop image into contenteditable in Chrome to the cursor(将图像拖放到 Chrome 中的 contenteditable 到光标处)