2016-08-11 91 views
3

我想弄清楚如何正确地将$ window服务注入到我的角度控制器中,然后测试以确保它适当地重定向。目前,我收到一条错误消息,说明undefined is not a constructor (evaluating 'expect(window.location.href).toEqual('/profile')')。我的角控制器的一个片段如下:

login.submitLogin = function(){ 
    LoginFactory.loginUser(login.dataset) 
     .then(function(response){ 
      $window.location.href = '/profile' 
     },function(response) { 
      login.errorMessage = response.data.message; 
     }); 
}; 

噶我的单元测试如下:

describe('Login Controller', function() { 

    var controller, window; 

    beforeEach(angular.mock.module('app')); 

    beforeEach(inject(function(_$controller_, _$window_){ 
     window = _$window_; 
     controller = _$controller_('LoginCtrl',window); 
    })); 

    describe('Login', function() { 

     it('expects controller to be defined', function(){ 
      expect(controller).to.be.defined; 
     }); 

     it('expects to be redirected after login', function() { 
      controller.dataset.username = 'username'; 
      controller.dataset.password = 'password'; 
      controller.submitLogin(); 
      expect(window.location.href).toEqual('/profile'); 
     }); 
    }); 
}); 
+0

正确的语法是'_ $ _控制器( 'LoginCtrl',{$窗口:窗口})'。并且''window''服务可以以这种方式提供给控制器而不是'window'。 – estus

+0

我将我的代码更改为以下内容:'$ window = _ $ window_; controller = _ $ controller _('LoginCtrl',{$ window:window});'在beforeEach中。我注入'expect($ window.location.href).toEqual('/ profile')',仍然得到异常。 Andrzej建议我需要模拟后端吗? –

+0

'{$ window:window}'没有意义,因为它已经等于'window'。你需要用'{location:{}}'对象存根'$ window'来不让控制器搞乱'window'全局,这就是它的意思。如果'LoginFactory'确实需要http请求,那么你也需要嘲笑它。进行单元测试来模拟所有测试单元(包括'LoginFactory')的最佳方式。 – estus

回答

4

一个解决方法就是模拟(覆盖)在您的测试$窗口服务:

beforeEach(function() { 
     module(function($provide) { 
      $provide.value('$window', { 
       location: {href: ''} 
      }); 
     }); 
    }); 

    beforeEach(inject(function(_$controller_, _$window_){ 
     window = _$window_; 
     controller = _$controller_('LoginCtrl',window); 
    })); 

,然后就检查什么已被分配到$ window.location.href:

expect(window.location.href).toEqual('/profile'); 

还需要使用$httpBackend如果LoginFactory.loginUser使得请求服务器:

it('expects to be redirected after login', function() { 
     var mockedResponse = {}; 

     controller.dataset.username = 'username'; 
     controller.dataset.password = 'password'; 

     $httpBackend.whenPOST('/api/login/').respond(mockedResponse); 
     controller.submitLogin(); 
     $httpBackend.flush(); 

     expect(window.location.href).toEqual('/profile'); 
    }); 
+1

它只是'module({$ window:{location:{href:''}})''。 – estus

相关问题