Для тестирования пользовательской проверки в AngularJS директивы



эта пользовательская директива проверки является примером, представленным на официальном сайте angular.
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.


я помещаю операторы печати везде, чтобы увидеть, что происходит, и похоже, что директива никогда не вызывается.
Что такое правильный способ проверить простой такая директива?

599   3  

3 ответов:

тесты другого ответа должны быть написаны как:

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. Это приводит форму в" грязное "состояние, иначе она останется" нетронутой", что, вероятно, не то, что вы хотите.

Я понял это, прочитав код углового приложения 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);
    });
  });
});

Я тестирую свои пользовательские директивы, ища в объекте "$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('[email protected]').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('[email protected]').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)
  }));
});

Я надеюсь, что смогу помочь вам!

Comments

    Ничего не найдено.