测试指令用作通用自定义验证器

时间:2014-08-23 06:34:05

标签: javascript angularjs angularjs-directive

我制作了自定义验证程序指令(不太通用的版本here),原因有两个:

  1. 我的模板中没有重复规则
  2. 我的规则服务中有复杂的规则,而不是分散在几个指令
  3. html / template看起来像这样:

    <input type='text' 
      name='name' 
      data-validator='name' 
      data-validator-entity='user'>
    

    指令:

    angular.module('app').directive('validator'
     , ['appRules', function(appRules) {
      return {
        require: ['^form','ngModel'],
        link: function(scope, elm, attrs, ctrls) {
          // removed checks that can be tested
          var ctrl=ctrls[1],form=ctrls[0]
          //appRules.user.validate('name') returns the function
          //  appRules.user.validateFunctions.name to validate
          //  the name field of the user entity
          ,fn=appRules[attrs.validatorEntity].validate(attrs.validator);
          ctrl.$parsers.unshift(
            function(viewValue){
              fn(viewValue,ctrl,form);
            }
          );
          //appRules.user.validateMessages.name is an array of possible
          //  things that can be wrong with name. Like cannotEmpty and 
          //  minimuThreeChars the validate function will set validity
          //  with ctrl.$setValidity('cannotEmpty',true/false);
          //  this is used to display a message to the user if needed
          //  for example:
          //  appSettings.messages.user.cannotEmpty='Cannot leave this field empty'
          ctrl.$error.messages=appRules[attrs.validatorEntity]
            .validateMessages[attrs.validator];
        }
      };
    }]);
    

    我唯一想测试的是ctrl。$ parsers上面设置了正确的函数,并且ctrl。$ error.messages设置正确。但是我不确定ctrl是什么,来自哪里以及如何在测试中访问它。

    到目前为止,这是测试:

    var $compile;
    var $rootScope;
    var appSettings;
    var appRules;
    var element;
    beforeEach(inject(function(_$compile_, _$rootScope_,appSettings,appRules){
      $compile = _$compile_;
      $rootScope = _$rootScope_;
      $rootScope.data={
        name:'testName'
      };
      appSettings = appSettings;
      appRules = appRules;
      element = $compile("<div><form name='test'>\
        <input type='text' \
          name = 'name' \
          data-ng-model='data.name'\
          data-validator-entity='user'\
          data-validator='name'></form></div>")($rootScope);
      $rootScope.$digest();
    }));
    
    //removed working tests that throw on invalid entity and field
    
    it('Check if validator sets correct values in ctrl.', function() {
      //how to get ctrl from here? element.find('input') is not it
      // element.find('input').data is empty 
      // element.find('input').$eror is undefined
    }
    

1 个答案:

答案 0 :(得分:1)

您可以在测试中获得这样的ngModel控制器:

var ctrl = element.find('input').controller('ngModel');

对于表单控制器,您可以这样做:

var form = element.find('form').controller('form');

希望这有帮助。