我有一个角度服务,做一些异步的东西(基于计时器).您可以使用计时器执行的操作之一是定义在计时器到期时触发的“处理程序”(如此伪代码中所示):
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)做我在代码矿深处做的事情,远离日光=)
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); })
我希望这很有用!我会留下它作为练习让读者弄清楚我为什么这样做=)