如何使用Sinon测试Ember.run.later?

时间:2014-02-20 01:02:46

标签: ember.js sinon

我有一些设置超时的Ember代码:

var MyObject = Ember.Object.extend({
  setFooToBarLater: function() {
    Ember.run.later(this, 'set', 'foo', 'bar', 500);
  }
});

我想用Sinon的假时钟测试一下。这是我试过的:

var clock = sinon.useFakeTimers();
var myObject = MyObject.create();
myObject.setFooToBarLater();
clock.tick(600);
expect(myObject.get('foo')).to.be('bar');

expect始终在set之前运行。我还尝试在运行循环中包装clock.tick

Ember.run(clock, 'tick', 600);

3 个答案:

答案 0 :(得分:4)

请注意sinon.useFakeTimers(默认情况下)会覆盖window.Date。一旦你已经有一个预定的Ember runloop并且useFakeTimers()被打开,那就成了一个问题。这是因为Backburner(Ember.js runloop实现)setTimeout / core调度方法/努力优化调用window.setTimeout(在ember.js中查找executeAt

在经历了sinon源之后,我制作了以下mod以让这两个相处得很好(gist)。它指示sinon不要触摸window.Date并修补sinon.test()在测试体之后等待几个滴答,允许预定的定时器执行和异步代码

sinon._originalUseFakeTimers = sinon.useFakeTimers;
sinon.useFakeTimers = function() {
    // make sure we don't override window.Date used in
    // Backburner.setTimeout() to optimize window.setTimeout() call numbers
    return sinon._originalUseFakeTimers.apply(this, [new Date().getTime(), "setTimeout", "setInterval", "clearTimeout", "clearInterval"]);
};

sinon._originalTest = sinon.test;
sinon.test = function(callback) {
    return sinon._originalTest.call(this, function() {
        callback.apply(this, arguments);

        // wait for further runloops to finish (2s is the mocha timeout)
        this.clock.tick(2000);
    });
};

答案 1 :(得分:3)

答案似乎没有将clock.tick置于运行循环中,而是实际调用Ember.run.later的调用。因此,以下 工作:

var clock = sinon.useFakeTimers();
var myObject = MyObject.create();
Ember.run(myObject, 'setFooToBarLater');
clock.tick(600);
expect(myObject.get('foo')).to.be('bar');

答案 2 :(得分:1)

使用ember 2.4.3和sinon 0.5.0似乎可以解决这类问题。 sinon.useFakeTimers()按预期工作,单元测试的代码类似:

const clock = sinon.useFakeTimers();
assert.expect(1);
var MyObject = Ember.Object.extend({
    setFooToBarLater: function() {
      Ember.run.later(this, 'set', 'foo', 'bar', 500);
    }
  }), myObject = MyObject.create();
myObject.setFooToBarLater();
clock.tick(600);
assert.equal(myObject.get('foo'), 'bar');
clock.restore();