unit testing - test - Para probar una directiva de validación angularjs personalizada
unit test angular 6 karma (3)
Esta directiva de validación personalizada es un ejemplo presentado en el sitio angular oficial. http://docs.angularjs.org/guide/forms Comprueba si la entrada de texto está en formato numérico o no.
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;
}
});
}
};
});
Para probar la unidad de este código, escribí esto:
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);
});
});
});
});
Entonces obtengo este error:
Expected undefined to equal 5.
Error: Expected undefined to equal 5.
Puse declaraciones de impresión en todas partes para ver qué está sucediendo, y parece que nunca se llama a la directiva. ¿Cuál es la forma correcta de probar una directiva simple como esta?
Las pruebas de la otra respuesta se deben escribir como:
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);
});
});
});
Tenga en cuenta que $scope.$digest()
ahora se invoca después de $setViewValue
. Esto establece la forma en estado "sucio", de lo contrario, se mantendría "prístino", que probablemente no es lo que desea.
Lo descubrí leyendo el código angular de la aplicación https://github.com/angular-app/angular-app Este video también ayuda a http://youtu.be/ZhfUv0spHCY?t=31m17s
Dos errores que cometí:
- No se vincule directamente al alcance cuando está haciendo ng-model
- Utilice el controlador de formulario para manipular directamente qué pasar para las directivas
Aquí está la versión actualizada. La directiva es la misma, solo la prueba que cambié.
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);
});
});
});
Pruebo mis directivas personalizadas buscando en el objeto "$ error" el nombre de la validación personalizada. Ejemplo:
''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)
}));
});
¡Espero que yo puedo ayudarle!