To test a custom validation angularjs directive
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.
I figured it out by reading angular-app code https://github.com/angular-app/angular-appThis 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); }); });});
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('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) }));});
I Hope i can help you!