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('/');
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('/');
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.