To test a custom validation angularjs directive
Solution 1:
The other answer's tests should be written as:
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);
});
});
});
Note that $scope.$digest()
now is invoked after $setViewValue
. This sets the form into “dirty” state, otherwise it would remain “pristine”, which probably is not what you want.
Solution 2:
I figured it out by reading angular-app code https://github.com/angular-app/angular-app This video also helps too http://youtu.be/ZhfUv0spHCY?t=31m17s
Two mistakes that I made:
- Do not bind directly to the scope when you are doing ng-model
- Use form controller to directly manipulate what to pass for directives
Here is the updated version. The directive is the same, only the test that I changed.
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);
});
});
});
Solution 3:
I test my custom directives searching in the object "$error" the name of the custom validation. Example:
'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)
}));
});
I Hope i can help you!