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.