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?
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.
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()
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With