jeudi 28 janvier 2016

Unit Test Angular Form Validation With $validators

My webapp is using Angular 1.4.8. I have a directive that validates a form input using $validators. Only input that starts with number 5, 6 and 9 and contains 8 numbers are valid.

angular
    .module('directive.customNumber', [])
    .directive('customNumber', customNumber);

function customNumber() {
    var REGEXP = /^([569][0-9]{7})/;

    return {
        require: ['ngModel', '^form'],
        link: function(scope, elm, attrs, ctrl) {
            ctrl.$validators.customNumber = function(modelValue, viewValue) {
                if(ctrl.$isEmpty(modelValue)) {
                    // consider empty models to be valid
                    return true;
                }
                return REGEXP.test(viewValue);
            };
        }
    };
}

Usage:

<form name="form">
    <input type="text" name="myInput" custom-number>
</form>

Now I want to write a unit test for this directive using Jasmine. This is my test case:

describe('Directive', function() {
    var $scope;

    beforeEach(function() {
        module('directive.customNumber');
        inject(function($rootScope, $compile) {
            $scope = $rootScope;
            var template = '<form name="form"><input type="text" name="myInput" custom-number></form>';
            $compile(template)($scope);
            $scope.digest();
        });
    });

    it('should not accept invalid input', function() {
        var form = $scope.form;
        form.myInput.$setViewValue('abc');

        expect(form.$valid).toBeFalsy();
        expect(form.myInput.$error.mobile).toBeDefined();
    });
});

Running this throws an error "TypeError: Cannot set property 'customNumber' of undefined at this line:

ctrl.$validators.customNumber = function(....

I am not sure why $validators become undefined in the test but works fine in normal environment. Even if I get rid of this error by manually creating $validators object before use, the test fails because the customNumber validator is never being run (know by logging), so form.$valid is always true.

How can I properly test this directive?

Aucun commentaire:

Enregistrer un commentaire