SimplGy
SimplGy

Reputation: 20437

Destroy a Backbone.Router and all Side effects after Creation

Let's say you want to be able to create a Backbone.Router instance that calls Backbone.history.start, destroy all traces of it, and create it again.

I need to do this for unit testing.

The problem is that creating a Backbone Router has global implications. Like Backbone.history, which is undefined until you make it.

var ReversibleRouter = Backbone.Router.extend({
  initialize: function(){
    _buildAppPaths(this.options) // Implementation not shown. Builds the application paths
    Backbone.history.start()
  },
  destroy: function(){
    // TODO: Implement this
  }
})

I'd like to be able to create and completely destroy so that I can do some unit testing on my application's implementation of the Router.

It it enough to call Backbone.history.stop() and set Backbone.history = undefined?

Upvotes: 4

Views: 1362

Answers (2)

SimplGy
SimplGy

Reputation: 20437

If you're looking to do more full stack integration types of testing, you can reset your application's router by using:

Backbone.history.stop()
Backbone.history = undefined // Could also probably use delete here :)

This has been successful so far--our tests probably instantiate and kill the router 5 times during our qunit testing. Works great.

Maybe mocking like @AdamTerlson is saying is the better way to go long term, but I'm still learning unit and integration testing philosophy. I don't mind having a full stack test or two, though.

Upvotes: 1

Adam Terlson
Adam Terlson

Reputation: 12730

This might be cheating, but I'm of the opinion you should be mocking functions outside of your unit of functionality that your testing and be especially sure your unit tests are not be allowed to hit the live DOM, server or the browser.

Look into SinonJS, it's great for this.

Here's an example of testing the initialize method of the router without ever affecting the browser history state.

test('...', function () {
    // Arrange
    var buildAppPaths = sinon.stub(ReversibleRouter.prototype, '_buildAppPaths');
    var startHistory = sinon.stub(Backbone.history, 'start');
    var options = {};

    // Act
    new ReversibleRouter(options);

    // Assert
    ok(buildAppPaths.calledWith(options));
    ok(startHistory.calledOnce); // or ok(Backbone.history.start.calledOnce);
});

Under this approach, you have successfully asserted that all calls were made to external units of functionality, including params. At that point, you can trust that the external call will do its job (proven by additional unit tests).

To make calls outside of this one unit would be doing integration tests and not unit tests.

Upvotes: 0

Related Questions