Testing routers in backbone.js properly?

Here’s a low-levelish way of doing it with jasmine, testing that pushState works as expected and that your router sets up things properly…
I assume a router that has been initialized and has a home route mapped to ”. You can adapt this for your other routes. I also assume you’ve done in your app initialization a Backbone.history.start({ pushState: true });

    describe('app.Router', function () {

        var router = app.router, pushStateSpy;

        it('has a "home" route', function () {
            expect(router.routes['']).toEqual('home');
        });

        it('triggers the "home" route', function () {
            var home = spyOn(router, 'home').andCallThrough();
            pushStateSpy = spyOn(window.history, 'pushState').andCallFake(function (data, title, url) {
                expect(url).toEqual("https://stackoverflow.com/");
                router.home();
            });
            router.navigate('');
            expect(pushStateSpy).toHaveBeenCalled();
            expect(home).toHaveBeenCalled();
            ...
        });
    });  

You can effectively achieve similar things by doing Backbone.history.stop(); it’s meant for this reason.

UPDATE: Browsers with no pushState:

This of course will work fine if your browser you test on has support for pushState. If you test against browsers that don’t, you can conditionally test as follows:

it('triggers the "home" route', function () {
    var home = spyOn(router, 'home').andCallThrough();

    if (Backbone.history._hasPushState) {
        pushStateSpy = spyOn(window.history, 'pushState').andCallFake(function (data, title, url) {
            expect(url).toEqual("https://stackoverflow.com/");
            router.home();
        });
        router.navigate('', {trigger: true});
        expect(pushStateSpy).toHaveBeenCalled();
        expect(home).toHaveBeenCalled();

    } else if (Backbone.history._wantsHashChange) {
        var updateHashSpy = spyOn(Backbone.history, '_updateHash').andCallFake(function (loc, frag) {
            expect(frag).toEqual('');
            router.home();
        });
        router.navigate('', {trigger: true});
        expect(updateHashSpy).toHaveBeenCalled();
        expect(home).toHaveBeenCalled();
    }
});

If you are on IE6, good luck.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)