Angular UI-Router testing scope inheritance

早过忘川 提交于 2019-12-12 01:07:26

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!