Sea*_*son 0 javascript backbone.js sinon
我的代码正常运行,但是我的测试用例由于其期望之一而失败。我不明白为什么我的间谍无法相信方法已经执行。
我像这样绑定事件监听器:
var playlists = Backbone.Collection.extend({
initialize: function(){
this.on('add', this._onAdd);
},
// Method:
_onAdd: function (model, collection, options) {
console.log('onAdd');
this._foo();
},
_foo: function(){
console.log('foo');
}
});
Playlists = new playlists();
Run Code Online (Sandbox Code Playgroud)
我正在用sinon监视我的对象:
it('should call _onAdd when adding a model to the collection', function() {
sinon.spy(Playlists, '_onAdd');
sinon.spy(Playlists, '_foo');
Playlists.add({});
expect(Playlists._onAdd.calledOnce).to.equal(true);
expect(Playlists._foo.calledOnce).to.equal(true);
Playlists._onAdd.restore();
Playlist._foo.restore();
});
Run Code Online (Sandbox Code Playgroud)
我的测试用例失败了,因为期望_onAdd一次被调用是不正确的。但是,_foo一次被调用的期望是正确的。
我在监视事件监听器方面做得不正确。为什么sinon不相信_onAdd被称为。我该如何纠正?
您的问题是由于被函数引用。当您在Playlists变数中建立播放清单时,它会initialize()在playlists集合上执行,而集合会建立参照的事件侦听器this._onAdd。
当您监视时,它会重新定义_onAdd指向的内容,但不会更新事件侦听器正在使用的引用。考虑以下:
_onAdd: function(){...} // Call this FuncRefA
Run Code Online (Sandbox Code Playgroud)
initialize(通过new playlists();)调用when时,将对事件侦听器进行评估以指向,FuncRefA因为这是评估时所指向的_onAdd。
this.on('add', FuncRefA);
Run Code Online (Sandbox Code Playgroud)
然后,当您添加间谍时,它实际上是在做这样的事情。
_onAdd: function(){ FuncRefA() } // Wraps the existing function, Call the new function FuncRefB
Run Code Online (Sandbox Code Playgroud)
在这一点上_onAdd现在指向FuncRefB,但该事件监听器是在仍然指向FuncRefA所以当你的测试运行事件侦听器被调用(和FuncRefA),但你的间谍不会被调用,因为事件侦听器不知道它的存在(它指向一个FuncRefA)
有两种解决方案:
1)您可以在创建之前prototype在playlists集合上设置间谍Playlists,这样Playlists创建时就是将功能引用给您的间谍
sinon.spy(playlists.prototype, '_onAdd');
Playlists = new playlists();
//... run tests now.
Run Code Online (Sandbox Code Playgroud)
2)使事件侦听器具有调用的匿名函数,_onAdd以便在事件发生时对其进行评估。这将允许您监视Playlists的_onAdd方法,因为一旦add事件触发,它的引用就会被评估。
initialize: function(){
var self = this;
this.on('add', function(){ self._onAdd(arguments) });
},
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2795 次 |
| 最近记录: |