Backbone.js 我如何测试主干模型';当使用Karma和Sinon时,绑定到事件总线的方法已触发?
当测试主干模型的事件已使用sinon spy触发时,它会错误地出错:Backbone.js 我如何测试主干模型';当使用Karma和Sinon时,绑定到事件总线的方法已触发?,backbone.js,karma-runner,sinon,backbone-events,sinon-chai,Backbone.js,Karma Runner,Sinon,Backbone Events,Sinon Chai,当测试主干模型的事件已使用sinon spy触发时,它会错误地出错:预期doSomething将被调用一次,但被调用0次,即使它似乎是在将控制台日志放入方法主体时执行的。测试功能如下所示: it('Y U NO WORK', function() { const events = {}; _.extend(events, Backbone.Events); const Model = Backbone.Model.extend({ initialize:
预期doSomething将被调用一次,但被调用0次
,即使它似乎是在将控制台日志放入方法主体时执行的。测试功能如下所示:
it('Y U NO WORK', function() {
const events = {};
_.extend(events, Backbone.Events);
const Model = Backbone.Model.extend({
initialize: function() {
this.listenTo(events, 'doSomething', this.doSomething);
},
doSomething: function() {},
});
const model = new Model();
const spy = sinon.spy(model, 'doSomething');
events.trigger('doSomething');
sinon.assert.calledOnce(spy);
});
我知道要解决这个问题,您必须将sinon-spy放在模型的原型上,比如const-spy=sinon.spy(Model.prototype,'doSomething')在new Model()
调用之前的行中的code>,但是当放入模型实例时,它似乎可以正常工作,如下所示:
it('And this does work', function() {
const Model = Backbone.Model.extend();
const model = new Model();
const spy = sinon.spy(model, 'set');
model.set('foo', 'bar');
sinon.assert.calledOnce(spy);
});
奇怪的是,为什么它需要在第一个实例中放在模型的原型上,而在第二个实例中却可以在模型实例上工作?Spy将原始方法替换为自定义方法,以便知道何时调用它(它保留对原始方法的引用,以便以后还原)。因此,在第一种情况下,您在创建spy之前设置了一个事件侦听器。事件系统实际上直接引用了原始方法,而不是间谍。Spy对此无能为力,Spy不知道何时调用它
在设置事件侦听器之前,需要先设置spy,例如:
it('Y U NO WORK', function() {
var spy;
const events = {};
_.extend(events, Backbone.Events);
const Model = Backbone.Model.extend({
initialize: function() {
spy = sinon.spy(this, 'doSomething');
this.listenTo(events, 'doSomething', this.doSomething);
//now same as this.listenTo(events, 'doSomething', spy);
},
doSomething: function() {},
});
const model = new Model();
events.trigger('doSomething');
sinon.assert.calledOnce(spy);
});
或者避免直接引用原始方法,如:
this.listenTo(events, 'doSomething', function() {
//by the time this is invoked, original has been replaced with spy
this.doSomething();
});
它之所以能工作,是因为它没有保存对原始方法的引用,方法调用是动态的