Saturday, November 12, 2011

Backbone.js History and Jasmine

‹prev | My Chain | next›

After a bit of refactoring in the jasmine specs of my Backbone.js calendar application, I am down to 11 failures:


Eleven failures is pretty impressive considering that I only have 9 specs, but hey, it is much improved from yesterday.

Upon closer inspection of my failing specs, I notice that nearly all of them are of the "Error: Backbone.history has already been started in http://localhost:8888/public/javascripts/backbone.js (line 778)" variety.

Looking into to the Backbone code, I see that an error is being thrown if a local variable, historyStarted, has been previously set to true:
    // Start the hash change handling, returning `true` if the current URL matches
    // an existing route, and `false` otherwise.
    start : function(options) {

      // Figure out the initial configuration. Do we need an iframe?
      // Is pushState desired ... is it available?
      if (historyStarted) throw new Error("Backbone.history has already been started");
//...
Looking through the Backbone code further, there is no mechanism for stopping or restarting the history. Since this variable is only set inside a closure, I have no chance of getting access to it externally either. Since it is a variable and not a method, I cannot even stub out method calls that gain access to it. In other words, I have no hope of fiddling with it in my tests.

This leaves the only alternative as altering my application code to allow me to test. That is never a good situation. I try to minimize the damage by keeping the fingerprint small. A try-catch ought to suffice:
  new Routes({application: application});
  try {
    Backbone.history.start();
  } catch (x) {
    console.log(x);
  }
And, in fact it does work. Now I am down to only four errors:


There is not much point in leaving the console.log() of the catch statement in place. This is the only throw in the History object. Still, I am loathe to swallow exceptions without some indication, so I leave it there. If nothing else, perhaps it will nag me to the point that I will submit a patch to Backbone to make testing a little easier.

Update: Looks as though there is an open pull request on this.

Day #203

No comments:

Post a Comment