How do I mock $window injected manually in provider private function?

匿名 (未验证) 提交于 2019-12-03 03:03:02

问题:

I have the following provider:

angular.module('MyApp').provider('MyDevice', function () {      var ngInjector = angular.injector(['ng']),         $window = ngInjector.get('$window');      function isMobileDevice () {         return (/iPhone|iPod|iPad|Silk|Android|BlackBerry|Opera Mini|IEMobile/)             .test($window.navigator.userAgent || $window.navigator.vendor || $window.opera);     }      this.$get = function () {         return {             isDesktop: function () {                 return !isMobileDevice();             },             isMobile: function () {                 return isMobileDevice();               }         };     };  }); 

And the following test spec:

describe('MyDeviceProvider', function () {      var myDevice;      beforeEach(function () {         inject(['MyDevice', function (_myDevice_) {             myDevice = _myDevice_;         }]);     });      it('Test #1', function () {         // Mock '$window.navigator.userAgent' to "desktop"         expect(myDevice.isDesktop()).toEqual(true);         expect(myDevice.isMobile()).toEqual(false);     });      it('Test #2', function () {         // Mock '$window.navigator.userAgent' to "mobile"         expect(myDevice.isDesktop()).toEqual(false);         expect(myDevice.isMobile()).toEqual(true);     });  }); 

My question is, how do I mock $window in both Test #1 and Test #2 so they are successful? I have tried with $provide.value and spyOn for countless objects, but I can't seem to mock the value of $window.navigator.userAgent to run my tests.

How do I solve this?

P.S: The code above acts only as a demonstration of my issue and I cannot change the provider into a service because of special requirements of the application.

回答1:

Very crudely, you could do the following:

describe('MyDeviceProvider', function () {      var myDevice,         $window,         navigator;      beforeEach(function () {         inject(['MyDevice', '$window', function (_myDevice_, _$window_) {             myDevice = _myDevice_;             $window = _$window_;         }]);          // Save the original navigator object         navigator = $window.navigator;     });      afterEach(function () {         $window.navigator = navigator;     });      it('Test #1', function () {         // Mock the entire navigator object to "desktop"         $window.navigator = {             userAgent: "desktop" // Use a real "desktop" user agent         };          // Mock '$window.navigator.userAgent' to "desktop"         expect(myDevice.isDesktop()).toEqual(true);         expect(myDevice.isMobile()).toEqual(false);     });      it('Test #2', function () {         // Mock the entire navigator object to "desktop"         $window.navigator = {             userAgent: "mobile" // Use a real "mobile" user agent         };         // Mock '$window.navigator.userAgent' to "mobile"         expect(myDevice.isDesktop()).toEqual(false);         expect(myDevice.isMobile()).toEqual(true);     });  }); 

You should test different mocks mimicking different browsers too.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!