Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

To test a custom validation angularjs directive

This custom validation directive is an example presented at the official angular site. http://docs.angularjs.org/guide/forms It checks a text input is in number format or not.

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;         }       });     }   }; }); 

To unit test this code, I wrote this:

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);       });     });   }); }); 

Then I get this error:

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

I put print statements everywhere to see what is going on, and it looks like the directive is never called. What is a proper way to test a simple directive like this?

like image 831
ghiden Avatar asked Mar 05 '13 09:03

ghiden


People also ask

What is testing in AngularJS?

Testing in AngularJS is achieved by using the karma framework, a framework which has been developed by Google itself. The karma framework is installed using the node package manager. The key modules which are required to be installed for basic testing are karma, karma-chrome-launcher ,karma-jasmine, and karma-cli.


1 Answers

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.

like image 70
jrief Avatar answered Sep 24 '22 21:09

jrief