我正在测试一段异步代码,其代码如下:
randomService.doSomething().then(function() {
console.log('I completed the operation!');
});
令人惊讶的是(对我而言)我发现它只是在jasmine的runs
函数中包含它时才成功(即显示了console.log输出),如下所示:
var isDone = false;
runs(function() {
randomService.doSomething().then(function(data) {
console.log('I completed the operation!');
isDone = true;
});
});
waitsFor(function() {
return isDone;
}, 'Operation should be completed', 1000);
据我了解,我认为waitsFor
只是为了延迟代码,换句话说,如果我有更多代码,我必须延迟直到异步调用完成后才会使用它 - 换句话说,我原本以为我没有理由使用runs
和waitsFor
,因为在这段代码之后没有任何内容,对吧?这是我从阅读这个问题得到的印象:What do jasmine runs and waitsFor actually do?但显然我在某些时候已经把自己搞砸了。
有没有人对此有任何想法?
修改 这是一个具有更多细节问题的Plunker: http://plnkr.co/edit/3qnuj5N9Thb2UdgoxYaD?p=preview
注意第一个测试总是如何通过,第二个测试失败了。 另外,我确定我之前应该提到过这个,但这是使用angularJS和Jasmine 1.3。
答案 0 :(得分:3)
我想我发现了这个问题。这是文章:http://blogs.lessthandot.com/index.php/webdev/uidevelopment/javascript/testing-asynchronous-javascript-w-jasmine/
基本上这是必要的,因为Jasmine在完成测试之前不会等待异步调用完成。根据这篇文章,如果一个调用需要足够长的时间并且稍后会有更多的测试,那么在原始测试完成之后,先前测试中的异步回调中的expect
语句最终可以完全在不同的测试中执行。
使用runs
和waitsFor
解决问题,因为它们强制茉莉等待waitsFor
完成,然后再进行下一次测试;这是一个有争议的问题,但是因为显然Jasmine 2.0以比1.3更好的方式处理异步测试,淘汰了runs
和waitsFor
。
答案 1 :(得分:0)
这就是茉莉花的运作方式。你链接的问题有一个很好的解释答案:
本质上,runs()和waitFor()函数填充数组 他们提供的功能。然后通过jamine处理阵列 其中,顺序调用函数。那些功能 由runs()注册后,预计会执行实际工作 由waitFor()注册的人应该是' latch'功能和意志 每隔10毫秒进行一次轮询(调用),直到它们返回true或者是可选的 注册超时期限到期。如果超时时间到期 使用可选的已注册错误消息报告错误; 否则,该过程继续进行数组中的下一个函数。
总结一下,每个waitsFor
来电都必须有相应的runs
来电。他们一起工作。 1}}在没有waitsFor
之前调用runs
之前没有任何意义。
我修订过的plunker(见这个答案的评论):http://plnkr.co/edit/9eL9d9uERre4Q17lWQmw
如您所见,我将$rootScope.$apply();
添加到您正在测试的超时功能中。这使得promise回调中的console.log
运行。但是,如果你忽略了使用xit
的其他测试,它只会运行,并且expect
之后的console.log
似乎不会被识别为Jasmine测试(尽管肯定必须运行,因为console.log
确实如此。
非常奇怪 - 我真的不明白为什么会这样,但我认为这与Jasmine如何在幕后工作,如何注册测试等等有关。我在这一点上的理解是,如果你在异步回调中有一个expect
,那么Jasmine就会认识到"它作为测试套件的一部分,除非在runs
内进行初始异步调用。
至于为什么会这样,我不知道。我不认为值得尝试理解 - 我只会使用runs
和waitsFor
而不用担心,但那只是我。如果您感觉受虐待,您可以随时挖掘信息来源。对不起,我无法提供更多帮助。