2014-07-19 52 views
1

如何使用$ stateChangeStart或其他發出的事件進行測試?

我有下面的代碼,這在本質上檢查用戶登錄,如果沒有,重定向到app.login狀態

app.run(function ($rootScope, $state, AuthenticationService) { 

    $rootScope.AuthenticationService = AuthenticationService 
    $rootScope.isLoggedIn = AuthenticationService.getIsLoggedIn 

    if (!$rootScope.isLoggedIn()) { 
    $state.go('app.login') 
    } 
    // Catch all errors on state change 
    $rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) { 
    $state.go('app.home') 
    }) 

    // Sets up the role requirements per state 
    $rootScope.$on('$stateChangeStart', function (event, toState) { 
    if (AuthenticationService.getIsLoggedIn()) { 
    } else { 
     if (toState && toState.name !== 'app.login') { 
     $state.go('app.login') 
     } 
    } 
    }) 
}) 

的測試,我想實現:

'use strict' 

describe('Controller', function() { 

    var $scope 
    , $state 
    , $rootScope 
    , AuthenticationService 
    , $controller 

    beforeEach(module('replanApp')) 

    beforeEach(inject(function ($injector) { 
    $state = $injector.get('$state') 
    $rootScope = $injector.get('$rootScope') 
    AuthenticationService = $injector.get('AuthenticationService') 
    $scope = $rootScope.$new() 
    $controller = $injector.get('$controller') 
    })) 

    describe('Initializers', function() { 
    it('should redirect to /login if the user is not logged in', function() { 
     $state.go('app.admin.index') 
     $rootScope.$apply() 
     assert.notOk(AuthenticationService.getIsLoggedIn()) 
     assert.equal($state.current.name, 'app.login') 
    }) 
    }) 
}) 

它基本上應該去一個狀態,然後$rootScope.$on('$stateChangeStart', fn(){})應該已經看到用戶沒有登錄,並將其轉移到app.login狀態。

但我正在逐漸AssertionError: expected 'app.admin.index' to equal 'app.login'

如何將一個實現與$ stateChangeStart和其他活動的測試?

+1

順便說一句,你必須在'$ state.go('app.login')'之前調用'event.preventDefault();'。 – xpepermint

回答

2

我會修改測試來檢查,看看是否$state.go已經被調用,而不是試圖去檢查當前的狀態是什麼與'app.login'

describe('Initializers', function() { 
    beforeEach(function(){ 
     spyOn($state,'go'); 
    }); 
    it('should redirect to /login if the user is not logged in', function() { 
     $state.transitionTo('app.admin.index'); 
     $rootScope.$apply(); 
     assert.notOk(AuthenticationService.getIsLoggedIn()); 
     expect($state.go).toHaveBeenCalledWith('app.login'); 
    }); 
    }); 

我不能保證,這將解決您的測試,但它會使它更像是一個單元測試,因爲它不會依賴$state.go來設置當前狀態。

+0

這樣做我得到'期待間諜被調用['app.login']但實際調用['app.admin.index'] ... – Boris

+0

編輯後 - 使用$ scope.transitionTo停止測試失敗與上述錯誤。 +1建議檢查$ state.go調用,而不是狀態改變本身,這是我從其他幾十個建議中唯一能夠幫助我的東西,它作爲一個單元測試更有意義。 – Boris