Testing backbone.js application with jasmine - how to test model bindings on a view?

Viewed 4361

I had some interesting tribulations in trying to test whether views were correctly bound to events.  In backbone, we typically bind to events in the initialize method, using something along the lines of: something.bind("change", this.render);.  In my test, I want to make sure that this binding is set up, so I did the following: 

this.myView = new MyView();
spyOn(this.myView, "render");;
this.legendView.groupData.trigger("change");
expect(this.legendView.render).toHaveBeenCalled();

But, that won't work.  Because the bind occurs in MyView's initialize function, the event get's bound to myView's render function AT THAT TIME.  So, when you add your spy, it wraps the render function and sets it back into place at myView.render.  But the closure created by the first bind still exists, and we are totally hozed.  So what can we do about it?  What I did, is move my bind call's to a seperate function, something like: 

myView = Backbone.View.extend({
initialize: function(){
    _.bindAll(this, "render");
    this.initialize_model_bindings();
},
initialize_model_bindings: function(){
    something.bind("change", this.render);
},
render: function(){ //... }
});

and my test then looks like:

this.myView = new MyView();
spyOn(this.myView, "render");
this.myView.initialize_model_bindings();
this.legendView.groupData.trigger("change");
expect(this.legendView.render).toHaveBeenCalled();

This works, but I'm looking for a better solution. Thanks

6 Answers
Related