使用jasmine测试backbone.js视图事件
我正在尝试为无处不在的backbone.js“todo”示例的Coffeescript实现实现视图测试(请参阅github.com/rsim/backbone\u Coffeescript\u演示) 除了查看事件之外,我对上述演示的jasmine测试工作得非常好。我想我会被以下一个或两个问题困扰I)我不理解视图代码中的事件绑定,ii)我不理解如何正确设置视图代码事件的Jasmine测试 下面是“编辑”事件的示例使用jasmine测试backbone.js视图事件,backbone.js,jasmine,jasmine-jquery,Backbone.js,Jasmine,Jasmine Jquery,我正在尝试为无处不在的backbone.js“todo”示例的Coffeescript实现实现视图测试(请参阅github.com/rsim/backbone\u Coffeescript\u演示) 除了查看事件之外,我对上述演示的jasmine测试工作得非常好。我想我会被以下一个或两个问题困扰I)我不理解视图代码中的事件绑定,ii)我不理解如何正确设置视图代码事件的Jasmine测试 下面是“编辑”事件的示例 class TodoApp.TodoView extends Backbone.Vi
class TodoApp.TodoView extends Backbone.View
tagName: "li"
template: TodoApp.template '#item-template'
events:
"dblclick div.todo-content" : "edit"
...
initialize: ->
_.bindAll this, 'render', 'close'
@model.bind 'change', @render
@model.bind 'destroy', => @remove()
render: ->
$(@el).html @template @model.toJSON()
@setContent()
this
edit: ->
$(@el).addClass "editing"
@input.focus()
...
…现在,我们来测试一下双击是否能获得焦点:
describe "edit state", ->
li = null
beforeEach ->
setFixtures('<ul id="todo-list"></ul>')
model = new Backbone.Model id: 1, content: todoValue, done: false
view = new TodoApp.TodoView model: model, template: readFixtures("_item_template.html")
$("ul#todo-list").append(view.render().el)
li = $('ul#todo-list li:first')
target = li.find('div.todo-content')
expect(target).toExist()
target.trigger('dblclick') # here's the event!
it "input takes focus", ->
expect(li.find('.todo-input').is(':focus')).toBe(true)
描述“编辑状态”,->
li=null
每次之前->
固定装置(“
”)
模型=新主干网。模型id:1,内容:todoValue,完成:false
视图=新建TodoApp.TodoView模型:模型,模板:readFixtures(“\u item\u template.html”)
$(“ul#todo list”).append(view.render().el)
li=$('ul#待办事项列表li:first')
target=li.find('div.todo-content')
expect(target.toExist())
target.trigger('dblclick')#事件发生了!
它“输入需要聚焦”,->
expect(li.find('.todo input').is(':focus')).toBe(true)
对i)间谍和ii)焦点的期望均未达到
测试backbone.js事件代码是否有我在Jasmine中应该知道的特殊性?您正在监视视图的
编辑方法。这将使用spy对象替换该方法,这意味着不会调用实际的edit方法。因此,您是@input。focus
永远不会触发
由于您希望测试实际调用您的编辑方法,因此我将为此删除spy
旁注:不要在beforeach中调用expect
方法。如果你真的需要对这些设置一个期望值,那么为它们创建一个it
块。我对coffescript不太在行,所以我可能遗漏了一些东西,但是你在哪里设置你的间谍
为了测试事件调用,您可能需要在设置spy后刷新视图的事件
spyOn(view, 'edit');
view.delegateEvents();
target.trigger('dblclick');
it("should call edit when target is double clicked", function() {
expect(view.edit).toHaveBeenCalled()
});
我没有用coffeescript写测试,但我也有同样的问题,所以我希望你能原谅我用javadccript回答。我把你的测试分为两个不同的测试。首先,我测试了调用视图的编辑函数是否将焦点设置在输入框上。之后,我测试了在双击标签时是否调用了编辑,但还没有通过测试。但下面是我如何测试编辑功能是否工作的
describe ("A todo item view", function() {
var my_model;
var todo_view;
beforeEach(function() {
my_model = new Todo({content:"todo value", done:false});
todo_view = new TodoView({model:my_model});
});
it("should set the focus on the input box when the edit function is called", function(){
$('body').append( todo_view.$el ); //append the view to Specrunner.html
todo_view.edit(); //call the view's edit function
var focus= document.activeElement; //finds what element on the page has focus
expect(focus).toBe('.todo-input'); //jasmine-jquery matcher checks if focused element has the .todo-input class
});
可能会导致问题的原因是,模型和视图都是在内部预先声明的。在beforeEach中声明它们意味着它们只存在于beforeEach的范围内,并且在运行it时不再存在
另外,setFixtures做了你认为它做的事情吗?焦点不能设置在不是DOM树一部分的元素上,因此我将视图的el附加到jasmine规范本身的主体上。(我使用的是HTML specrunner,而不是命令行版本),这使它成为dom树的一部分,因此允许它具有焦点,并使它是否具有焦点可测试。这方面的问题是主干。Viewevents
对象正在使用。对于能够被称为work的事件,元素必须是DOM的一部分,您可以通过执行类似于$('body').append(someView.el)
的操作来实现这一点。就个人而言,我尽量不测试主干网是否正确设置了事件
并手动触发单击,对于单元测试来说,直接调用回调处理程序更为实际,因为完全避免DOM,这会大大降低测试的速度
对于:focus
也是同样的问题,DOM中必须有一个元素,以便jQuery可以判断元素是否被聚焦。在这种情况下,最好将某些状态设置为组件的一部分,而不要通过查询DOM来检查状态,例如:someView.hasFocus==true
。或者,您可以监视元素focus
实现,并检查它是否被调用。谢谢,我已经删除了任何Jasmine间谍,但仍然无法获得预期的焦点。我认为您令人困惑的间谍和存根。间谍会包装方法,但允许调用通过。我遇到了同样的问题。你找到解决方法了吗?也有类似的问题,还是没有想法?