角度JS单元测试控制器

时间:2015-10-14 20:02:53

标签: angularjs karma-jasmine

我有一个像这样的控制器

    (function(){
        var app = angular.module('app', []);

        app.directive('test', function(){
            return {
                restrict: 'E',
                templateUrl: 'test.html',
                controller: ['$scope', function ($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_){
    // The injector unwraps the underscores (_) from around the parameter names when matching
    $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('$scope', { $scope: $scope });
      $scope.password = 'longerthaneightchars';
      $scope.grade();
      expect($scope.strength).toEqual('strong');
    });
  });
});

我最终得到了一个错误 错误:[ng:areq]参数' $ scope'不是一个功能,未定义

我正以正确的方式去帮助

3 个答案:

答案 0 :(得分:1)

您的控制器被定义为指令定义的一部分,我不认为这些可以独立于指令themsleves进行单元测试。

如果你想对这个控制器进行单元测试,你应该使用angular controller方法给它一个单独的名称,然后在你的指令中按名称使用它。然后,您可以使用angular-mock $controller服务检索控制器,类似于您现在的操作方式。最终结果如下:

app.controller('YourCtrl', ['$scope', function($scope) { ... }]);
app.directive('test', function() {
   return {
          ...
          controller: 'YourCtrl',
          ...
   }});

并在测试中

var controller = $controller('YourCtrl', { $scope: $scope });

这是一个puts it all together

的jsFiddle

答案 1 :(得分:0)

以下是我如何测试指令的控制器。 DEMO http://plnkr.co/edit/w9cJ6KDNDvemO8QT3tTN?p=preview

我不会导入控制器。我会编译指令并测试指令的控制器。

describe('PasswordController', function() {
  var $scope;
  var element;

  beforeEach(module('MyApp'));

  beforeEach(
    inject(function($rootScope, $compile, $templateCache) {
      // Imports test.html
      var templateUrl = 'test.html';
      var req = new XMLHttpRequest();
      req.onload = function () {
        $templateCache.put(templateUrl, this.responseText);
      };
      req.open('get', templateUrl, false);
      req.send();

      $scope = $rootScope.$new(); 

      element = '<test></test>';
      // Compile the directive 
      element = $compile(element)($scope);

      // Call digest cycle
      $scope.$apply();
    }));

  describe('$scope.grade', function() {
    it('sets the strength to "strong" if the password length is >8 chars', function() {
      $scope.password = 'longerthaneightchars';
      $scope.grade();
      expect($scope.strength).toEqual('strong');
    });
  });
});

答案 2 :(得分:-1)

您无法通过$scope创建$scope = {}。将您的规格更改为:

describe('PasswordController', function () {
    beforeEach(module('app'));

    var $controller, $rootScope;

    beforeEach(inject(function (_$controller_, _$rootScope_) {
            // The injector unwraps the underscores (_) from around the parameter names when matching
            $controller = _$controller_;
            $rootScope = _$rootScope_;
        }));

    describe('$scope.grade', function () {
        it('sets the strength to "strong" if the password length is >8 chars', function () {
            var $scope = $rootScope.$new();
            var controller = $controller('$scope', {
                    $scope : $scope
                });
            $scope.password = 'longerthaneightchars';
            $scope.grade();
            expect($scope.strength).toEqual('strong');
        });
    });
});