我有一些设置超时的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);
答案 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();