我一直试图为我的Auth控制器编写单元测试,但我无法解决此错误:
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});
})
}
以下是我的spec文件代码的一部分:
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的参数才能清除此错误?这就是我一直试图做的但没有运气。
******************** EDIT ********************
我嘲笑$状态,正如答案中所解释的那样: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 :(得分:0)
错误意味着$ scope.user未定义。您可以在创建控制器之前模拟它。
$scope = $rootScope.$new();
$scope.user = { username: 'foo' };
答案 1 :(得分:0)
您的afterEach
失败,因为您有待处理的http请求。
我看到您正在注入$state
,在这种情况下$state
将被实例化,并且将执行默认路由。这就是正在获取其中一个控制器main.html
的模板的原因。
要绕过此操作,请使用假人替换go()
和transitionTo()
个$state
方法:
beforeEach( inject( function ( _$state_ ) {
state = _$state_;
spyOn( state, 'go' );
spyOn( state, 'transitionTo' );
} ) );