Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

testing backbone.js view events with jasmine

I'm trying to implement view tests for a Coffeescript implementation of the ubiquitous backbone.js 'todo' example (see github.com/rsim/backbone_coffeescript_demo.)

My jasmine tests of the above demo work pretty well, except for view events. I expect I am stuck on one or both of the following i) I do not understand the event binding in the view code, ii) I do not understand how to properly set up the Jasmine test of the view code events.

Here is an example of the 'edit' event...

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()
  ...

...now here's a test of whether focus was gained upon double clicking:

    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)

The expectation on neither i) the spy nor ii) the focus is met.

Is there a peculiarity to testing backbone.js event code about which I should be aware in Jasmine?

like image 346
Lille Avatar asked Sep 28 '11 23:09

Lille


2 Answers

you're spying on the view's edit method. this replaces the method with a spy object, which means the actual edit method won't get called. therefore, you're @input.focus will never fire.

since you want the test to actually call your edit method, i would remove the spy for it.

side note: don't call expect methods in your beforeEach. if you truly need to set an expectation on those, create an it block for them.

like image 182
Derick Bailey Avatar answered Nov 09 '22 05:11

Derick Bailey


I'm not great with coffescript so I might be missing something but where are you setting up your spy?

In order to test event calling you may need to refresh the view's events once you've set up the spy.

spyOn(view, 'edit');
view.delegateEvents();
target.trigger('dblclick');

it("should call edit when target is double clicked", function() {
  expect(view.edit).toHaveBeenCalled()
});
like image 34
daddywoodland Avatar answered Nov 09 '22 06:11

daddywoodland