backbone.js点击事件间谍不会使用jasmine.js和sinon.js调用
backbone.js click event spy is not getting called using jasmine.js and sinon.js
我正在尝试使用backbone.js、jasmine.js和sinon.js测试按钮点击。但下面的测试用例失败了。我正在使用间谍来跟踪它是否被呼叫。你能帮我做这个吗?
谢谢。
新任务模板
<script id='new_task_template' type='text/template'>
<input type='text' id='new_task_name' name='new_task_name'></input>
<button type='button' id='add_new_task' name='add_new_task'>Add Task</button>
</script>
新建任务视图
T.views.NewTaskView = Backbone.View.extend({
tagName: 'section',
id: 'new_task_section',
template : _.template ( $("#new_task_template").html() ),
initialize: function(){
_.bindAll( this, 'render', 'addTask');
},
events:{
"click #add_new_task" : "addTask"
},
render: function(){
$(this.el).html( this.template() );
return this;
},
addTask: function(event){
console.log("addTask");
}
});
Jasmine测试用例
describe("NewTaskView", function(){
beforeEach( function(){
this.view = new T.views.NewTaskView();
this.view.render();
});
it("should #add_new_task is clicked, it should trigger the addTask method", function(){
var clickSpy = sinon.spy( this.view, 'addTask');
$("#add_new_task").click();
expect( clickSpy ).toHaveBeenCalled();
});
});
茉莉花输出
NewTaskView
runEvents
runshould #add_new_task is clicked, it should trigger the addTask method
Expected Function to have been called.
问题是在主干已经将点击事件直接绑定到addTask函数之后添加间谍(它在构建视图的过程中这样做)。因此,你的间谍不会被传唤。
在构建之前,尝试将间谍附加到View的原型上
this.addTaskSpy = sinon.spy(T.views.NewViewTask.prototype, 'addTaskSpy');
this.view = new T.views.NewTaskView();
然后记得删除它:
T.views.NewViewTask.prototype.addTaskSpy.restore()
events:{
"click" : "addTask"
},
意味着您正在将单击事件绑定到视图的this.el
根元素,在您的情况下,该元素的ID为new_task_section
。你需要将它绑定到#add_new_task
,我想这是你的"添加任务"按钮——这应该会解决它!
events:{
"click #add_new_task" : "addTask"
},
更新:
$("#add_new_task")找不到元素,因为视图没有添加到文档DOM树中。使用this.view.$('#add_new_task')
,它应该可以在视图中存储的分离片段中搜索元素。
您的方法存在一些问题。首先,你要监视你想要测试的类,这不是单元测试的工作方式,因为你测试的是类的内部逻辑,而不是它的行为。其次,这也是测试失败的原因,因为您没有将视图el附加到DOM中。因此,要么将el附加到DOM,要么将click事件直接激发到el:$('#add_new_task', this.view.el).click()
。
Btw。创建元素和绑定事件的主干方式使得编写好的单元测试变得困难,因为您不得不使用DOM和jquery。编写可测试代码的更好方法是始终将所有依赖项传递给构造函数,不要在代码中创建新实例,因为很难测试这些对象。因此,在您的情况下,将el对象作为jquery对象注入构造函数并手动在事件中注入会容易得多。通过这种方式,您可以在不依赖DOM或jquery的情况下测试类。
因此,在您的情况下,构造函数将如下所示:
initialize: function(){
this.el.click(_.bind( this, 'addTask'));
}
你的测试:
var el = {click: function(){}};
spyOn( el, 'click');
new T.views.NewTaskView({el: el});
expect(el.click).toHaveBeenCalled(); //test the click event was bind
//call the function that was bind to the click event,
//which is the same as trigger the event on a real DOM object
el.click.mostRecentCall.args[0]()
毕竟,你必须决定什么方法能满足你的需求。具有主干助手的Leanner代码,或对jquery、DOM和主干依赖较少的可测试代码。
- 如何使用Jasmine测试Knockout.js点击绑定
- 什么'与Jasmine相比,使用Sinon.js的优势是什么;内置于间谍
- 当使用Jasmine在JS中测试AJAX调用时,.andReturn(..)和.respondWith(
- 如何在Jasmine中运行js函数
- Jasmine在全局窗口对象上创建本地JS函数的Spy
- 如何在ajax请求和it上测试并获得完整的代码覆盖率's使用Jasmine和Blanket.js对jQuery
- Jasmine找不到Backbone.js模型
- Jasmine规格与Velocity.js动画失败$.Velocity.mock=true
- json需要JS插件+jasmine
- 如何在Jasmine测试中包含Ext JS
- Jasmine 不从“src”目录加载 js 文件
- 在 Node.js 中使用 Jasmine 测试子进程发送
- 如何使用 Jasmine.js 来测试控制台输出
- 如何使用Jasmine JS拦截简单的jQuery函数
- Jasmine + Node.js用于服务器端单元测试.如何运行测试
- 如果“.jshintrc”和“karma.conf.js”,Jasmine“test”文件夹的一部分受到版本控制
- 使用 Jasmine-node 对 Node.js 进行单元测试
- 如何在Jasmine中每次测试后自动恢复所有sinon.js间谍
- 使用frisby.js或jasmine节点测试证书过期
- 测试Angular.js控制器,而不使用Jasmine嘲笑工厂