如何用注射测试控制器

时间:2016-02-02 14:10:59

标签: angularjs unit-testing controller

如何使用注入测试AngularJS控制器,例如:

angular.module('app', []).controller('PasswordController', passwordController);
     passwordController.$inject = ['$scope'];
     //does not exist in the documentation angularjs
   function passwordController($scope) {
      $scope.password = '';
      $scope.grade = function() {
        var size = $scope.password.length;
        if (size > 8) {
          $scope.strength = 'strong';
        } else if (size > 3) {
          $scope.strength = 'medium';
        } else {
          $scope.strength = 'weak';
        }
      };
   }

我无法在测试编写中获得控制器

describe('PasswordController', function() {
  beforeEach(module('app'));
  var $controller;
  beforeEach(inject(function(_$controller_){
       $controller = _$controller_;
  }));

  describe('$scope.grade', function() {
    it('sets the strength to "strong" if the password length is >8 chars', function() {
      var $scope = {};
      var controller = $controller('PasswordController', { $scope: $scope });
      // TypeError: 'undefined' is not a function (evaluating '$controller('PasswordController');
      $scope.password = 'longerthaneightchars';
      $scope.grade();
      expect($scope.strength).toEqual('strong');
    });
  });
});

使用AngularJS文档的控制器模型,我设法运行测试:https://docs.angularjs.org/guide/unit-testing

1 个答案:

答案 0 :(得分:0)

正确方向的一个步骤是正确实例化$scope变量:

var $rootScope, $scope, $controller;
beforeEach(inject(function(_$rootScope_, _$controller_) {
    $rootScope = _$rootScope_;
    $scope = $rootScope.$new();
    $controller = _$controller_;
}));

describe('PasswordController', function() {
    var ctrl = $controller('PasswordController',{$scope: $scope});
    // Tests
});

另一件事 - 肯定是在karma.conf.js文件中包含控制器的源代码而你是否在控制器中调用该函数?它看起来不像你......

编辑

好的,所以我已经把你的代码整合到我的代码中。这是一个功能齐全的测试套件,适用于您所编写的内容以及对实际控制器的一些重写:

控制器:

(function() {
  'use strict';

  angular
    .module('app')
    .component('example', {
      bindings: {},
      controllerAs: "vm",
      controller: "PasswordController",
      templateUrl: 'example.html'
    });

  angular
    .module('app')
    .controller('PasswordController', PasswordController);

  function PasswordController(){
    var vm = this;
    vm.password = '';

    vm.grade = function() {
      var size = vm.password.length;
      if (size > 8) {
        vm.strength = 'strong';
      } else if (size > 3 && < 8) {
        vm.strength = 'medium';
      } else {
        vm.strength = 'weak';
      }
    };
  }
})();

测试(全部通过):

(function() {
    'use strict';

    describe('PasswordController', function() {

        var $rootScope, $scope, ctrl;
        beforeEach(module('app'));

        beforeEach(inject(function(_$rootScope_, $controller) {
            $rootScope  = _$rootScope_;
            $scope      = $rootScope.$new();

            ctrl = $controller('PasswordController',{$scope: $scope});
        }));

        describe('PasswordController', function() {
            it('should be defined', function() {
                expect(ctrl).toBeDefined();
            });
            it('should initalize password to ""', function() {
                expect(ctrl.password).toBe('');
            });
            describe('grade()', function() {
                it('should set strength to "strong" if size is greater than 8', function() {
                    ctrl.password = 'password1';
                    ctrl.grade();

                    expect(ctrl.strength).toBe('strong');
                });
                it('should set strength to "medium" if size is greater than 3', function() {
                    ctrl.password = 'pass';
                    ctrl.grade();

                    expect(ctrl.strength).toBe('medium');
                });
                it('should set strength to "weak" if size is less than 3', function() {
                    ctrl.password = 'ps';
                    ctrl.grade();

                    expect(ctrl.strength).toBe('weak');
                });
            });
        });
    });
}());