我试图通过存根Backbone.View的listenTo回调方法来实现一个简单的测试。
但是,我似乎无法直接执行此操作 - 我必须将回调包装在匿名函数中。知道为什么会发生这种情况,我怎么能避免使用包装器并仍然能够存回回调?
这不起作用:
// MyView.js
var MyView = Backbone.View.Extend({
initialize: function() {
this.listenTo('some:event', this.myFunc);
},
myFunc: function() {
//.. do useful stuff
}
});
// Trying to stub with sinon
var view = new MyView();
sinon.stub( view, 'myFunc' );
view.trigger('some:event');
view.myFunc.called; // is false;
然而,这有效:
// MyView.js
var MyView = Backbone.View.Extend({
initialize: function() {
this.listenTo('some:event', function() { this.myFunc });
},
myFunc: function() {
//.. do useful stuff
}
});
// Trying to stub with sinon
var view = new MyView();
sinon.stub( view, 'myFunc' );
view.trigger('some:event');
view.myFunc.called; // is true;
答案 0 :(得分:4)
您可以在创建视图的原型之前将其存根:
sinon.stub(MyView.prototype, 'myFunc');
var view = new MyView();
view.trigger('some:event');
view.myFunc.called; // is true;
Sinon还有Util function名为createStubInstance
。但是,我从未尝试过,所以我不知道它有多好用;
sinon.createStubInstance(MyView);
编辑以解决评论(以相当松散的术语):
由于prototypal inheritance works的方式以及JS通过引用传递函数的方式。首次创建视图的实例时,myFunc
指向MyView.prototype.myFunc
的引用。这意味着当调用initialize
函数时,listenTo
事件处理程序已设置,并且它正在使用当时对myFunc
的引用。
创建视图后对myFunc
函数进行存根只会更改view.myFunc指向的引用(它将更改为新的存根函数引用而不是MyView.prototype.myFunc
引用)。但这不会改变listenTo
使用的引用。
解决问题的一种方法是做你做的事情:
this.listenTo('some:event', function() { this.myFunc() });
这解决了问题,方法是将listenTo
指向一个匿名函数,该函数在事件触发器上运行时,将在调用时从视图中评估myFunc
,这将是存根参考。
解决此问题的另一种方法是对原型函数进行存根,因此在创建实例时,myFunc
使用的listenTo
引用是存根函数。
希望这有帮助。