2014-12-07 219 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'); 
    }));