单元测试中未调用Angular Directive函数

时间:2018-01-16 17:55:53

标签: javascript angularjs unit-testing angularjs-directive

我在Angular(1.2.29)中构建了一个新指令,我试图使用karma测试它,但是在检查字段是否无效时我遇到了一些问题,它似乎始终有效。< / p>

这是我的指示:

var EmailOrUrlValidation = function emailOrUrlValidation() {

        console.log("on directive 0");

        return {
            require: 'ngModel',
            restrict: 'A',
            scope: {
                checkDirty: '=validationCheckDirty'
            },
            link: function (scope, element, attrs, ctrl) {

                console.log("on directive 1");

                scope.$watch(function () {
                    scope.checkDirty = scope.checkDirty ? true : false;
                    element.attr('maxlength', 50);
                    ctrl.$parsers.unshift(validateEmailOrUrl);
                    ctrl.$formatters.unshift(validateEmailOrUrl);
                });

                function validateEmailOrUrl(value) {
                    console.log("on directive 2");
                    var urlRegexp = "myurlregex";
                    var emailPattern = "myemailregex";

                    if (!value) { 
                        ctrl.$setValidity("valid", true);

                    } else if (scope.checkDirty && !ctrl.$dirty) { 
                        ctrl.$setValidity("valid", true);

                    } else { 
                        var emailRegex = new RegExp(emailPattern);

                        var emailOrUrlValid = urlRegexp.test(value) || emailRegex.test(value);
                        ctrl.$setValidity("valid", emailOrUrlValid);
                    }
                    return value;
                }
            }
        };
    };

 this.app = angular.module('shared.validations', [])
                     .directive('emailOrUrlValidation', [emailOrUrlValidation])

这是我的单元测试(我按照此示例https://stackoverflow.com/a/22772504/1031021):

describe('EmailOrUrlValidation tests', function () {
    var $scope, form, element;
    beforeEach(module("shared.validations"));
    beforeEach(inject(function ($compile, $rootScope) {
        $scope = $rootScope;
        element = angular.element(
            '<form name="form">' +
                '<input data-ng-model="model.emailorurl" name="emailorurl" email-or-url-validation data-ng-required="true" validation-check-dirty="true" />' +
            '</form>'
        );
        $scope.model = { emailorurl: null }
        $compile(element)($scope);
        form = $scope.form;
    }));
    describe('invalid url', function () {
        it('should pass with valid url', function () {

            form.emailorurl.$setViewValue('www.google.pt');
            $scope.$digest();

            expect(form.emailorurl.$invalid).to.be.false;
        });
        it('should not pass with invalid url', function () {

            form.emailorurl.$setViewValue('testing');
            $scope.$digest();

            expect(form.emailorurl.$invalid).to.be.true;
        });
    });
});

然而其中一个断言失败了,因为$ invalid总是假的......

我在函数 validateEmailOrUrl 中插入了一些日志,并且它从未显示在我的控制台上,但是在函数外部出现了日志,我认为该函数没有被触发。

有人能帮助我吗?这有什么不对?

1 个答案:

答案 0 :(得分:0)

我让它工作,将我的单元测试更改为以下内容:

describe('EmailOrUrlValidation tests', function() {

    var $scope,
        form,
        element;

    beforeEach(module("shared.validations"));

    beforeEach(inject(function($compile, $rootScope) {
        $scope = $rootScope;
        element = angular.element(
            '<form name="form">' +
            '<input data-ng-model="model.emailorurl" name="emailorurl" email-or-url-validation data-ng-required="true" validation-check-dirty="true" />' +
            '</form>'
        );

        $scope.model = { emailorurl: null }
        $compile(element)($scope);
        form = $scope.form;
    }));

    describe('invalid url', function () {
        it('email address without domain should not be valid', function () {
            $scope.$digest();
            var dirElementInput = element.find('input');
            angular.element(dirElementInput).val('teste@www').trigger('input');
            expect(form.emailorurl.$valid).to.be.false;

        });

        it('email address with domain should be valid', function () {
            $scope.$digest();
            var dirElementInput = element.find('input');
            angular.element(dirElementInput).val('teste@www.com').trigger('input');
            expect(form.emailorurl.$valid).to.be.true;

        });

        it('url address starting with http should not be valid', function() {
                $scope.$digest();
                var dirElementInput = element.find('input');
                angular.element(dirElementInput).val('http://www.google.com').trigger('input');
                expect(form.emailorurl.$valid).to.be.false;

        });

        it('url address starting with https should not be valid', function () {
            $scope.$digest();
            var dirElementInput = element.find('input');
            angular.element(dirElementInput).val('https://www.google.com').trigger('input');
            expect(form.emailorurl.$valid).to.be.false;

        });

        it('url address starting without http should be valid', function () {
            $scope.$digest();
            var dirElementInput = element.find('input');
            angular.element(dirElementInput).val('www.google.pt').trigger('input');
            expect(form.emailorurl.$valid).to.be.true;

        });

        it('random text should not be valid', function () {
            $scope.$digest();
            var dirElementInput = element.find('input');
            angular.element(dirElementInput).val('jdsfvdsfg').trigger('input');
            expect(form.emailorurl.$valid).to.be.false;

        });
    });
});