首页 文章

测试自定义验证angularjs指令

提问于
浏览
75

此自定义验证指令是官方角度站点上提供的示例 . http://docs.angularjs.org/guide/forms它检查文本输入是否为数字格式 .

var INTEGER_REGEXP = /^\-?\d*$/;
app.directive('integer', function() {
  return {
    require: 'ngModel',
    link: function(scope, elm, attrs, ctrl) {
      ctrl.$parsers.unshift(function(viewValue) {
        if (INTEGER_REGEXP.test(viewValue)) {
          // it is valid
          ctrl.$setValidity('integer', true);
          return viewValue;
        } else {
          // it is invalid, return undefined (no model update)
          ctrl.$setValidity('integer', false);
          return undefined;
        }
      });
    }
  };
});

为了对这段代码进行单元测试,我写道:

describe('directives', function() {
  beforeEach(module('exampleDirective'));

  describe('integer', function() {
    it('should validate an integer', function() {
      inject(function($compile, $rootScope) {
        var element = angular.element(
          '<form name="form">' +
            '<input ng-model="someNum" name="someNum" integer>' +
          '</form>'
          );
        $compile(element)($rootScope);
        $rootScope.$digest();
        element.find('input').val(5);
        expect($rootScope.someNum).toEqual(5);
      });
    });
  });
});

然后我收到这个错误:

Expected undefined to equal 5.
Error: Expected undefined to equal 5.

我把print语句放在任何地方,看看发生了什么,看起来永远不会调用该指令 . 测试像这样的简单指令的正确方法是什么?

3 回答

  • 84

    其他答案的测试应写成:

    describe('directives', function() {
      var $scope, form;
      beforeEach(module('exampleDirective'));
      beforeEach(inject(function($compile, $rootScope) {
        $scope = $rootScope;
        var element = angular.element(
          '<form name="form">' +
          '<input ng-model="model.somenum" name="somenum" integer />' +
          '</form>'
        );
        $scope.model = { somenum: null }
        $compile(element)($scope);
        form = $scope.form;
      }));
    
      describe('integer', function() {
        it('should pass with integer', function() {
          form.somenum.$setViewValue('3');
          $scope.$digest();
          expect($scope.model.somenum).toEqual('3');
          expect(form.somenum.$valid).toBe(true);
        });
        it('should not pass with string', function() {
          form.somenum.$setViewValue('a');
          $scope.$digest();
          expect($scope.model.somenum).toBeUndefined();
          expect(form.somenum.$valid).toBe(false);
        });
      });
    });
    

    请注意, $scope.$digest() 现在在 $setViewValue 之后调用 . 这将表单设置为“脏”状态,否则它将保持“原始”状态,这可能不是您想要的 .

  • 2

    我通过读取角度应用程序代码https://github.com/angular-app/angular-app想出来了这个视频也有帮助http://youtu.be/ZhfUv0spHCY?t=31m17s

    我犯的两个错误:

    • 在进行ng-model时,不要直接绑定到作用域

    • 使用表单控制器直接操作指令传递的内容

    这是更新版本 . 该指令是相同的,只是我改变的测试 .

    describe('directives', function() {
      var $scope, form;
      beforeEach(module('exampleDirective'));
      beforeEach(inject(function($compile, $rootScope) {
        $scope = $rootScope;
        var element = angular.element(
          '<form name="form">' +
            '<input ng-model="model.somenum" name="somenum" integer />' +
          '</form>'
        );
        $scope.model = { somenum: null }
        $compile(element)($scope);
        $scope.$digest();
        form = $scope.form;
      }));
    
      describe('integer', function() {
        it('should pass with integer', function() {
          form.somenum.$setViewValue('3');
          expect($scope.model.somenum).toEqual('3');
          expect(form.somenum.$valid).toBe(true);
        });
        it('should not pass with string', function() {
          form.somenum.$setViewValue('a');
          expect($scope.model.somenum).toBeUndefined();
          expect(form.somenum.$valid).toBe(false);
        });
      });
    });
    
  • 67

    我测试我的自定义指令在对象“$ error”中搜索自定义验证的名称 . 例:

    'use strict';
    
    describe('Directive: validadorCorreo', function () {
    
      // load the directive's module
      beforeEach(module('sistemaRegistroProCivilApp'));
    
      var inputCorreo, formulario, elementoFormulario, scope, $compile;
    
      beforeEach(inject(function ($rootScope, _$compile_) {
        scope = $rootScope.$new();
        $compile = _$compile_;
    
        elementoFormulario = angular.element('<form name="formulario">' + 
          '<input type="text" name="correo" data-ng-model="correo" required data-validador-correo/>' + 
          '</form');
        scope.correo = '';
        elementoFormulario = $compile(elementoFormulario)(scope);
        scope.$digest();
        inputCorreo = elementoFormulario.find('input');
        formulario = scope.formulario;
        console.log(formulario.correo.$error);
      }));
    
      it('Deberia Validar si un correo ingresado en el input es correcto e incorrecto', inject(function ($compile) {
    
        inputCorreo.val('eric+@eric.com').triggerHandler('input');
        expect(formulario.correo.$error.email).toBe(true); //Here, the name of the custom validation appears in the $error object.
        console.log(formulario.correo.$error);
    
        inputCorreo.val('eric@eric.com').triggerHandler('input');
        expect(formulario.correo.$error.email).toBeUndefined();//Here, the name of the custom validation disappears in the $error object. Is Undefined
        console.log(formulario.correo.$error.email)
      }));
    });
    

    我希望我能帮助你!

相关问题