2016-08-11 77 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

相關問題