Ben*_*rts 6 javascript qunit backbone.js sinon
在以下单元测试代码中:
TestModel = Backbone.Model.extend({
defaults: {
'selection': null
},
initialize: function() {
this.on('change:selection', this.doSomething);
},
doSomething: function() {
console.log("Something has been done.");
}
});
module("Test", {
setup: function() {
this.testModel = new TestModel();
}
});
test("intra-model event bindings", function() {
this.spy(this.testModel, 'doSomething');
ok(!this.testModel.doSomething.called);
this.testModel.doSomething();
ok(this.testModel.doSomething.calledOnce);
this.testModel.set('selection','something new');
ok(this.testModel.doSomething.calledTwice); //this test should past, but fails. Console shows two "Something has been done" logs.
});
Run Code Online (Sandbox Code Playgroud)
第三个ok失败,即使该函数是从主干事件绑定中有效调用的,如控制台演示的那样.

这非常令人沮丧,并且让我对sinon.js是否适合测试我的骨干应用程序感到震惊.我做错了什么,或者这是一个问题,sinon如何检测是否已经调用了某些东西?有解决方法吗?
编辑:这是我的具体例子的解决方案,基于接受答案的猴子补丁方法.虽然它在测试中有几行额外的设置代码,(我不再需要模块功能)但它完成了工作.谢谢,mu is too short
test("intra-model event bindings", function() {
var that = this;
var init = TestModel.prototype.initialize;
TestModel.prototype.initialize = function() {
that.spy(this, 'doSomething');
init.call(this);
};
this.testModel = new TestModel();
. . . // tests pass!
});
Run Code Online (Sandbox Code Playgroud)
mu *_*ort 12
呼叫this.spy(this.testModel, 'doSomething')替换testModel.doSomething用的方法新的包装方法:
var spy = sinon.spy(object,"method");
创建一个间谍,
object.method并用间谍替换原始方法.
所以this.spy(this.testModel, 'doSomething')有效地做这样的事情:
var m = this.testModel.doSomething;
this.testModel.doSomething = function() {
// Spying stuff goes here...
return m.apply(this, arguments);
};
Run Code Online (Sandbox Code Playgroud)
这意味着testModel.doSomething在绑定事件处理程序时,它是一个不同的函数initialize:
this.bind('change:selection', this.doSomething);
Run Code Online (Sandbox Code Playgroud)
在你附上间谍之后.Backbone事件调度程序将调用原始doSomething方法,但该方法没有Sinon检测.当您doSomething手动调用时,您将调用spy添加的新函数,并且该函数具有Sinon检测.
如果你想使用Sinon测试你的Backbone事件,那么你必须安排spy在绑定任何事件处理程序之前将Sinon 调用应用于模型,这可能意味着挂钩initialize.
也许你可以修补你的模型,initialize以便spy在它绑定任何事件处理程序之前添加必要的调用:
var init = Model.prototype.initialize;
Model.prototype.initialize = function() {
// Set up the Spy stuff...
init.apply(this, arguments);
};
Run Code Online (Sandbox Code Playgroud)
演示:http://jsfiddle.net/ambiguous/C4fnX/1/
您还可以尝试使用以下内容对您的模型进行子类化:
var Model = Backbone.Model.extend({});
var TestModel = Model.extend({
initialize: function() {
// Set up the Spy stuff...
Model.prototype.initialize.apply(this, arguments);
}
});
Run Code Online (Sandbox Code Playgroud)
然后使用TestModel替代模型,这将给你的仪表版本Model中TestModel,而无需里面包含您的正常生产就绪了一堆测试代码Model.缺点是使用的任何其他内容都Model需要进行子类化/修补/ ... TestModel而是使用.
演示:http://jsfiddle.net/ambiguous/yH3FE/1/
您可以通过以下方式TestModel解决问题:
var OriginalModel = Model;
Model = Model.extend({
initialize: function() {
// Set up the Spy stuff...
OriginalModel.prototype.initialize.apply(this, arguments);
}
});
Run Code Online (Sandbox Code Playgroud)
但你必须得到正确的订购,以确保每个人都使用新的Model而不是旧的.
演示:http://jsfiddle.net/ambiguous/u3vgF/1/
| 归档时间: |
|
| 查看次数: |
3630 次 |
| 最近记录: |