I'm using Backbone and Require.js. Everything works great but, I would like to add some unit tests to my application. I decided use Qunit.js.
In my main.js file I create new object EventsView
:
require.config({
paths: {
jquery: 'libs/jquery',
underscore: 'libs/underscore',
backbone: 'libs/backbone',
qunit: 'test/libs/qunit-1.10.0
}
});
require(['view/eventsView',
'test/eventsView_test',
'test/eventView_test' ], function(EventsView){
var events = new EventsView; //here I create first object my View
});
In eventsView.js initialize
I render the main view
define(['jquery',
'backbone',
'underscore',
'collection/eventC',
'model/eventM',
'view/eventView'], function($, Backbone,_,EventC,EventM, EventView,){
var EventsView = Backbone.View.extend({
el: $(".contener"),
initialize: function(){
this.render();
},
....//other functions
});
return EventsView;
});
So now I need to call functions from this view in other file eventsView_test.js. I can't do it like this because the View will be rendered again:
define(['jquery','qunit','view/eventsView'], function($,qunit,EventsView){
//var eventsView = new EventsView(); // I can't create object here
test( "first_test_func", function() {
var result = eventsView.first_test_func(2,2);
equal( result, 4, "2 square equals 4" );
});
What should I do? Do I need some kind of singleton or something else?
Fantastic question, and one that I see all the time.
I actually solved this by creating what I dubbed a "bootstrap" paradigm, but call it whatever you want. The key is that the Backbone view does not render itself, but instead whomever consumes it is responsible for that. You'll run into issues with fetch() and the like, so thankfully this solves that too.
The goal: Don't unit test render and just skip it all together!
Your view becomes something like this:
How this would be consumed in your app:
This can now be unit tested without worry.
Use SinonJS
I strongly recommend checking out SinonJS. It's amazing for unit testing JavaScript, particularly Backbone implementations due to its powerful mocking which can be used from preventing the rendering and server calls (
fetch
,save
, etc) from actually hitting the server while still allowing you to assert they got called.