如何在Mocha测试中模拟时间流逝,以便setTimeout回调被调用?

48

我需要测试依赖于setTimeout的JavaScript代码,以执行定期任务。 我该如何在我的Mocha测试中模拟时间的流逝,以便setTimeout回调被调用?

我基本上是在寻求类似于Jasmine的Mock Clock的功能,它允许您通过多个滴答声来推进JavaScript时间。

1个回答

68

我发现Sinon.JS支持通过sinon.useFakeTimers操作JavaScript时钟,如其Fake Timers文档所述。这非常完美,因为我已经使用Sinon进行模拟,而且我想这也是有道理的,因为Mocha本身不支持这一点,它更多地属于模拟库的领域。

以下是使用Mocha/Chai/Sinon的示例:

var clock;
beforeEach(function () {
     clock = sinon.useFakeTimers();
 });

afterEach(function () {
    clock.restore();
});

it("should time out after 500 ms", function() {
    var timedOut = false;
    setTimeout(function () {
        timedOut = true;
    }, 500);

    timedOut.should.be.false;
    clock.tick(510);
    timedOut.should.be.true;
});

为什么需要 beforeEach 和 afterEach? - R01010010
1
@Rimbuaj,为了在每次测试之前安装模拟时钟并在之后删除它? - aknuds1
1
但是只有一个测试...这就是我问的原因。 - R01010010
8
养成一个好习惯很重要。每当你需要为测试做设置/拆卸时,聪明的做法是使用before/after配对,这样就不会忘记其中之一了。 - Danny Andrews
4
如果你没有在每个测试的 afterEach 中写入 clock.restore(),并且测试中的任何内容抛出异常,那么 setTimeout 等基于时间的函数将始终被覆盖。通过使用 afterEach,您可以确保它们始终被恢复为默认设置。 - Will Munn
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接