Mocking $window in an angularJS test

When trying to mock the angularJS internal $window factory, I recently stumbled about an error message when running the test:

TypeError: Cannot read property 'userAgent' of undefined
	    at $SnifferProvider.$get (C:/projects/hwa-mobile/src/main/external-libs/angular.js:8327:72)
	    at Object.invoke (C:/projects/hwa-mobile/src/main/external-libs/angular.js:2864:28)
	    at C:/projects/hwa-mobile/src/main/external-libs/angular.js:2702:37
	    at getService (C:/projects/hwa-mobile/src/main/external-libs/angular.js:2824:39)
	    at Object.invoke (C:/projects/hwa-mobile/src/main/external-libs/angular.js:2842:13)
	    at C:/projects/hwa-mobile/src/main/external-libs/angular.js:2702:37
	    at getService (C:/projects/hwa-mobile/src/main/external-libs/angular.js:2824:39)
	    at Object.invoke (C:/projects/hwa-mobile/src/main/external-libs/angular.js:2842:13)
	    at C:/projects/hwa-mobile/src/main/external-libs/angular.js:2702:37
	    at getService (C:/projects/hwa-mobile/src/main/external-libs/angular.js:2824:39)

The test looked something like this:

describe('myService', function () {
	beforeEach(function () {
		module("myModule",function ($provide) {
			$provide.factory('$window', function () {
				return jasmine.createSpy('$windowmock');
			});
		});
		....
	});

	it('should do something', function () {
		...
	});
});

Apparently angularJS itself tries to read the userAgent even when running inside a mocked environment.

The solution was quite easy:

describe('myService', function () {
	beforeEach(function () {
		module("myModule",function ($provide) {
			$provide.factory('$window', function () {
				var windowmock = jasmine.createSpy('$window);
				windowmock.navigator = window.navigator;
				return windowmock;
			});
		});
		....
	});

	it('should do something', function () {
		...
	});
});

The navigator property of the jasmine mock object will be the original navigator property of the original window object. Smells a bit, but works.

Leave a Reply

Your email address will not be published. Required fields are marked *

*