使用Jasmine

时间:2015-07-01 10:14:59

标签: javascript angularjs unit-testing jasmine

Jasmine是以BDD方式对javascript代码进行单元测试的最广泛使用的测试框架之一。我试图将它用于AngularJS组件测试。 AngularJS文档提供以下示例代码

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 });
      $scope.password = 'longerthaneightchars';
      $scope.grade();
      expect($scope.strength).toEqual('strong');
    });
  });
});

因此上面的代码使用了角度模拟库,并通过依赖注入通过控制器处理范围。现在我有一个范围对象,其中包含我的控制器分配给它的函数和对象。我可以很好地测试它。高兴。

现在有趣的是,如果我想测试未与范围相关联的函数。例如,下面的doSomethingVeryCoolThatNeedsTesting函数

angular.module('app', [])
.controller('PasswordController', 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';
    }

   function doSomethingVeryCoolThatNeedsTesting() {
    ....  
   }

  };
});

似乎每当我使用$controller('PasswordController', { $scope: $scope });时,它都会返回一个填充的$scope对象和undefined控制器对象。

TL; DR

有没有办法可以测试没有链接到范围的角度控制器函数?

2 个答案:

答案 0 :(得分:5)

没有。如果您没有将内部控制器功能暴露给外部世界,那么这些功能是私有的,请参阅revealing module pattern

因此问题不是测试框架的角度问题,问题是javascript语言本身。

如果你想测试一个内部函数,你必须让它对外部可见。选项包括:

  1. 将其暴露在$ scope对象
  2. 暴露于任何其他强烈劝阻且可能无法通过测试访问的全局对象

答案 1 :(得分:1)

我会选择其中一种解决方案:

  1. 如果它是私人功能,也许它不应该直接测试,而是通过公共api
  2. 如果它是一个实用功能,那么也许它应该在它自己的控制器/服务中作为公共api
  3. 否则你必须污染你的控制器api。我建议不要。迟早有一个开发人员会开始使用这个半隐藏函数