2014-12-07 218 views
1

我一直想寫一個單元測試我的驗證控制器,但我不能讓過去的這個錯誤傳遞PARAMS:

TypeError: Cannot read property 'username' of undefined 

以下是在我寫一個測試控制器的功能:

$scope.signup = function() { 
    authFactory.signup($scope.user) 
    .then(function (res) { 
     $window.localStorage.setItem('token', res.token); 
     $window.localStorage.setItem('current_user', res.username); 
     $state.go('dashboard', {username: $scope.user.username}); 
    }) 
    } 

下面是我的規格文件中的部分代碼:

beforeEach(inject(function(_$rootScope_, _$window_, _$httpBackend_, authFactory, _$controller_, _$state_) { 
    $rootScope = _$rootScope_; 
    $window = _$window_; 
    $httpBackend = _$httpBackend_; 
    authFactory = authFactory; 
    $scope = $rootScope.$new(); 
    $state = _$state_; 

    var $controller = _$controller_; 
    createController = function() { 
    return $controller('AuthController', { 
     $scope: $scope, 
     $window: $window, 
     $state: $state, 
     authFactory: authFactory 
    }); 
    }; 
    createController(); 
})); 

帶有$ state.go的行導致錯誤。老實說,我不完全確定爲什麼這個錯誤被拋出。我是否需要表示傳遞給$ state.go的參數以清除此錯誤?這就是我一直試圖做的,但沒有運氣。

********************編輯********************

I嘲笑$狀態在回答了說明:UI-router interfers with $httpbackend unit test, angular js

現在,我得到這些錯誤:

Chrome 39.0.2171 (Mac OS X 10.10.1) AuthController "after each" hook FAILED 

Error: Unexpected request: GET ./modules/main/main.html 
No more request expected 

這裏是我的測試代碼:

describe('AuthController', function() { 
var createController; 
var $scope; 
var $rootScope; 
var state; 
var $httpBackend; 
var $window; 

beforeEach(function() { 
    module('stateMock'); 
    module('myApp'); 
}); 
beforeEach(inject(function(_$rootScope_, _$window_, _$httpBackend_, _$controller_, _$state_) { 
    $rootScope = _$rootScope_; 
    $window = _$window_; 
    $httpBackend = _$httpBackend_; 
    $scope = $rootScope.$new(); 
    state = _$state_; 
    $scope.user = {username: 'foo'}; 


    var $controller = _$controller_; 
    createController = function() { 
    return $controller('AuthController', { 
     $scope: $scope, 
     $window: $window, 
     state: state 
    }); 
    }; 
    createController(); 
})); 

afterEach(function() { 
    $httpBackend.verifyNoOutstandingExpectation(); 
    $httpBackend.verifyNoOutstandingRequest(); 
    $window.localStorage.removeItem('token'); 
    $window.localStorage.removeItem('current_user'); 
}); 
it('should store a token in localStorage after signup', function() { 
    var token = 'abcdefg'; 
    $httpBackend.expectPOST('/api/users/signup').respond({token: token}); 
    $scope.signup(); 
    $httpBackend.flush(); 
    state.expectTransitionTo('dashboard'); 
    state.ensureAllTransitionsHappened(); 
    expect($window.localStorage.getItem('token')).to.equal(token); 
}); 

回答

0

錯誤意味着$ scope.user未定義。你可以在創建控制器之前模擬它。

$scope = $rootScope.$new(); 
$scope.user = { username: 'foo' }; 
+0

這讓我過去的錯誤。現在,我正在看到這個: \t錯誤:無法從狀態'' – user3667725 2014-12-07 08:58:12

+0

解析'儀表板'您是否已將$ stateProvider配置添加到測試代碼中? – 2014-12-07 11:24:37

+0

「儀表板」狀態必須定義爲過渡到。或者你可以模擬$ state,這樣你就不需要包含你的$ stateProvider配置。 – 2014-12-07 11:27:27

0

afterEach失敗,因爲你已經掛起的HTTP請求。

我看到您正在注入$state,在這種情況下,$state將被實例化並且將執行默認路由。這就是爲什麼你的一個控制器main.html的模板正在被抓取。

要繞過這一點,用假人代替go()$state方法transitionTo()

beforeEach(inject(function (_$state_) { 
     state = _$state_; 
     spyOn(state, 'go'); 
     spyOn(state, 'transitionTo'); 
    }));