使用jasmine测试backbone.js视图事件

使用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

我正在尝试为无处不在的backbone.js“todo”示例的Coffeescript实现实现视图测试(请参阅github.com/rsim/backbone\u Coffeescript\u演示)

除了查看事件之外,我对上述演示的jasmine测试工作得非常好。我想我会被以下一个或两个问题困扰I)我不理解视图代码中的事件绑定,ii)我不理解如何正确设置视图代码事件的Jasmine测试

下面是“编辑”事件的示例

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树的一部分,因此允许它具有焦点,并使它是否具有焦点可测试。

    这方面的问题是主干。View
    events
    对象正在使用。对于能够被称为work的事件,元素必须是DOM的一部分,您可以通过执行类似于
    $('body').append(someView.el)
    的操作来实现这一点。就个人而言,我尽量不测试主干网是否正确设置了
    事件
    并手动触发单击,对于单元测试来说,直接调用回调处理程序更为实际,因为完全避免DOM,这会大大降低测试的速度


    对于
    :focus
    也是同样的问题,DOM中必须有一个元素,以便jQuery可以判断元素是否被聚焦。在这种情况下,最好将某些状态设置为组件的一部分,而不要通过查询DOM来检查状态,例如:
    someView.hasFocus==true
    。或者,您可以监视元素
    focus
    实现,并检查它是否被调用。

    谢谢,我已经删除了任何Jasmine间谍,但仍然无法获得预期的焦点。我认为您令人困惑的间谍和存根。间谍会包装方法,但允许调用通过。我遇到了同样的问题。你找到解决方法了吗?也有类似的问题,还是没有想法?