问题
I am trying to write units tests for a nested state. The state inherits some scope elements from the parent state. In my tests I am creating the controller, which obviously has no visibility of the parent state, and therefore no visibility of the inherited scope items.
it('should show the account page', inject(['$controller', 'security', function ($controller, security){
// set up controller with a scope
var $scope = $rootScope.$new();
// the parent controller calls this
var user = { first: 'First', last: 'Last', email: 'testuser@test.com', gender:'male', hasPassword:true};
$httpBackend.when('GET', '/api/user/current-user').respond(200, user);
$controller('AccountViewCtrl', { $scope: $scope});
$rootScope.$digest();
// verify the initial setup
//scope attributes defined on the parent controller
expect($scope.user).toEqual(user);
expect($scope.account).toEqual(user);
// scope attribute defined on the controller
expect($scope.genders.length).toEqual(2);
expect($scope.editable).toBe(false);
expect($scope.editCheck()).toBe(false);
}]));
The AccountCtrl defines a number of elements needed by all child states.
.controller('AccountCtrl', ['$scope', 'security', function ($scope, security){
$scope.user = security.requestCurrentUser();
$scope.account = angular.copy($scope.user);
}])
The AccountViewCtrl defines the other elements, but inherits the elements from the parent AccountCtrl
.controller('AccountViewCtrl', ['$scope', function ($scope) {
$scope.editable = false;
$scope.genders = [
{ name: 'Male', value: 'male' },
{ name: 'Female', value: 'female' }
];
$scope.editCheck = function(){
return $scope.editable;
};
....
}])
The tests are failing as I am only instantiating the controller and there is no visibility of the parent state and associated elements. Is there a best practice approach to testing ui-router states?
回答1:
Scope inheritance is a feature of Angular. I therefore think that it is not necessary to test in my tests.
My workaround is to test that the AccountCtrl works and then just put the values in the other tests:
it("should set scope when account Ctrl loaded", inject(['$controller', 'security', function($controller, security){
// Add your behavior testing code here
var $scope = $rootScope.$new();
var user = { first: 'First', last: 'Last', email: 'testuser@test.com', gender:'male', birthday:'password'};
security.currentUser = user;
$controller('AccountCtrl', { $scope: $scope});
$rootScope.$digest();
// verify the initial setup
expect($scope.user).toEqual(user);
expect($scope.account).toEqual(user);
}]));
Then in the other tests I manually populate the values:
it('should set scope on account page', inject(['$controller', 'I18N.MESSAGES', function ($controller, i18nMessages){
// set up controller with a scope
var $scope = $rootScope.$new();
var user = { first: 'First', last: 'Last', email: 'testuser@test.com', gender:'male', birthday:'password'};
$scope.account = $scope.user = user;
...
}]));
来源:https://stackoverflow.com/questions/17860277/angular-ui-router-testing-scope-inheritance