Reputation: 71
I am trying to test drive a view event using Jasmine and the problem is probably best explained via code.
The view looks like:
App.testView = Backbone.View.extend({
events: { 'click .overlay': 'myEvent' },
myEvent: function(e) {
console.log('hello world')
}
The test looks something like:
describe('myEvent', function() {
it('should do something', function() {
var view = new App.testView();
view.myEvent();
// assertion will follow
});
});
The problem is that the view.myEvent method is never called (nothing logs to the console). I was trying to avoid triggering from the DOM. Has anyone had similar problems?
Upvotes: 0
Views: 1439
Reputation: 35920
(Like I commented in the question, your code looks fine and should work. Your problem is not in the code you posted. If you can expand your code samples and give more info, we can take another look at it. What follows is more general advice on testing Backbone views.)
Calling the event handler function like you do is a legitimate testing strategy, but it has a couple of shortcomings.
event
argument or the test will not work.I prefer to test my views all the way from the event:
var view = new View().render();
view.$('.overlay').click();
expect(...).toEqual(...);
Like you said, it's generally not advisable to manipulate DOM in your tests, so this way of testing views requires that view.render
does not attach anything to the DOM.
The best way to achieve this is leave the DOM manipulation to the code that's responsible for initializing the view. If you don't set an el
property to the view (either in the View.extend
definition or in the view constructor), Backbone will create a new, detached DOM node as view.el
. This element works just like an attached node - you can manipulate its contents and trigger events on it.
So instead of...
View.extend({el: '#container'});
...or...
new View({el:'#container'});
...you should initialize your views as follows:
var view = new View();
$("#container").html(view.render().el);
Defining your views like this has multiple benefits:
render
method does some complicated DOM manipulation, it's faster to perform it on an detached node.IMHO, this view rendering pattern is a general best practice, not just a testing-related special case.
Upvotes: 5