【问题标题】:Angular Directive function not being called in Unit Testing单元测试中未调用角度指令函数
【发布时间】:2018-06-25 12:19:34
【问题描述】:

我在 Angular (1.2.29) 中构建了一个新指令,并尝试使用 karma 对其进行测试,但是在检查该字段是否无效时遇到了一些问题,它似乎始终有效。

这是我的指令:

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 中插入了一些日志,但它从未显示在我的控制台上,但是出现了函数之外的日志,我假设该函数没有被触发。

有人可以帮助我吗?这里有什么问题?

【问题讨论】:

  • 文档建议$setViewValue 不会触发对模型验证器的调用。通过将值分配给$scope.model.emailorurl,尝试直接在测试中更新 ng-model。我还假设您已经用真正的正则表达式替换了urlRegexpemailPatterndocs.angularjs.org/api/ng/type/…
  • 我尝试了您的解决方案,将 form.emailorurl.$setViewValue('testing') 替换为 $scope.model.emailorurl = "testing" 但仍然无效,我的指令中的函数 validateEmailOrUrl 是没有触发 :( 是的,我使用的是真正的正则表达式,我只是没有将它们粘贴到那里,因为它与问题无关并且会使问题太大......你还有其他解决方案吗?谢谢

标签: javascript angularjs unit-testing angularjs-directive


【解决方案1】:

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

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;

        });
    });
});

【讨论】:

    猜你喜欢
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2020-11-11
    • 2015-01-24
    相关资源
    最近更新 更多