我有一个角度服务,可以执行一些异步操作(基于计时器)。您可以使用计时器执行的操作之一是定义在计时器到期时触发的“处理程序”(如此伪代码中所示):
flag = false;
timer = new Timer(1000); // ms
timer.handler = function () { flag = true };
在这个简单的情况下,计时器会在1秒后将标志设置为true。我如何使用Angular / Karma / Jasmine进行单元测试?
通过阅读文档,我希望这可以工作:
...
flag = false;
timer = new Timer(1000);
timer.handler = function () { flag = true };
expect(flag).toBe(false);
sleep(2)
expect(flag).toBe(true);
...
而不是在道德上直立,那个测试决定失败了:
ReferenceError: Can't find variable: sleep
经过一些阅读,显然我不能使用角度场景与Jasmine。好的,我很酷。
更新:根据评论,我测试了我的“工作”settimeout方法。它永远不会被调用。
所以这样做:
...
flag = false;
timer = new Timer(1000);
timer.handler = function () { flag = true };
expect(flag).toBe(false);
setTimeout(function () { expect(flag).toBe(true) }, 2000);
...
但感觉有点奇怪。
问题:有更好的方法吗?
有趣的琐事:是的,我知道$ timeout。我有非常好的理由(TM)来做我在代码矿中做的深刻的事情,远离日光=)
答案 0 :(得分:11)
Jasmine有一种方法可以使用waits()或waitsFor()和runs()进行异步测试。看here。
代码如下:
...
flag = false;
timer = new Timer(1000);
timer.handler = function () { flag = true };
expect(flag).toBe(false);
waitsFor( function() {
return flag;
}, "timer ran");
runs( function() {
expect(flag).toBe(true);
});
...
OP注意
这是正确的解决方案,因此我将其标记为已接受。实际上我最终实现了基于此解决方案的类似睡眠的方法,并希望分享以防其他人有用。
在测试文件中:
function loiter(ms) {
var loiter = true;
setTimeout(function () {loiter = false}, ms);
waitsFor( function () {return !loiter}, "Loitered too long", ms + 50);
}
it("should ...", function () {
flag = false;
timer = new Timer(1000);
timer.handler = function () {flag = true};
setTimeout(function () {expect(flag).toBe(true)}), 1100);
loiter(1200);
})
我希望这很有用!我会留下它作为练习让读者弄清楚我为什么这样做=)