JS学习之Jasmine中的timeout

最近被Jasmine中的异步超时弄得崩溃了,具体问题就是setTimeout,有时导致测试用例超时,有时又没有等待足够的时间。因此下定决心研究一下Jasmine中异步超时的用法。

首先,看看jasmine文档给的例子:

describe("long asynchronous specs", function() {
    var originalTimeout;
    beforeEach(function() {
        originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
        jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
    });

    it("testTimeout", function(done) {
        setTimeout(function() {
            done();
        }, 9000);
    });

    afterEach(function() {
        jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
    });
});

这个例子非常简单,运行testTimeout这个用例时也大约停顿了9秒,测试结果为:

SPEC HAS NO EXPECTATIONS testTimeout

这个结果还算正常,因为测试用例中没有任何测试期望,如果加上expect(1).toEqual(1);语句,就不会提示上面的信息了。

接下来,仿照上面的代码写了一个例子:

describe("TimeOutTest", function() {
    var value = 0;

    beforeEach(function() {
        jasmine.clock().install();
    });

    afterEach(function() {
        jasmine.clock().uninstall();
    });

    it("testTimeout", function(done) {
        console.log("start testTimeout ...");
        expect(value).toEqual(0);
        setTimeout(function() {
            console.log("timeout callback");
            value++;
            done();
        }, 2000);

        console.log("after timeout");
        expect(value).toEqual(1);
    });
});

但结果出乎意料之外,有两个错误:

  1. expect(value).toEqual(1); 这句failed,此时value的值为0。仔细一想,value值确实是0,因为setTimeout函数虽然设置了超时回调,但这个函数本身并不会阻塞在这儿,而是会接着往下执行。
  2. 提示错误:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

这个错误就有些不理解了,和上一个例子的代码差不多,为什么这个不会回调到超时callback呢?如果回调了,执行了done(); 就不会出现上述的超时错误。

再研究jasmine的例子,将上述的例子修改如下:

describe("TimeOutTest", function() {
    var value = 0;

    beforeEach(function() {
        jasmine.clock().install();
    });

    afterEach(function() {
        jasmine.clock().uninstall();
    });

    it("testTick", function(done) {
        console.log("start testTick ...");
        expect(value).toEqual(0);
        setTimeout(function() {
            console.log("timeout callback");
            value++;
            done();
        }, 2000);

        console.log("after timeout");
        jasmine.clock().tick(2001);
        expect(value).toEqual(1);
    });
});

这次测试用例运行正确,秘诀就在于引入了jasmine.clock().tick()函数,这个函数运行会有两个后果:

  1. 它会阻塞javascript代码的执行,相当于C程序中的sleep函数。
  2. 超时之后回调到setTimeout中的设置的callback,在上面的例子中,会执行到value++,所以expect(value).toEqual(1);这句测试得以通过。

再回头看第二个例子,问题出在哪儿呢?原因在于jasmine.clock().install();这句话,它实际上会改写系统的setTimeout函数,它将会同步等待一段时间过去,这个时候就需要借助于jasmine.clock().tick()来休眠一段时间。如果没有这句话,测试用例会等待,直到jasmine.DEFAULT_TIMEOUT_INTERVAL超时。如果第三个例子中jasmine.clock().tick(2001);改为小于2000的一个值,会是什么情况呢?答案就是出现jasmine.DEFAULT_TIMEOUT_INTERVAL超时,也就是等待的时间不够长,不会触发setTimeout超时。

总结:

  1. jasmine.clock().install()/jasmine.clock().uninstall()要和jasmine.clock().tick()配合使用。

以上的完整代码可参考我在github上的项目jsdemo.

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云水木石

但行好事,莫问前程

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值