【问题标题】:Angular Directive link function click does not get called in Jasmine unit test在 Jasmine 单元测试中未调用 Angular Directive 链接功能单击
【发布时间】:2016-10-08 15:41:58
【问题描述】:

我有一个 Angular 指令,它通过检测打开模式的组件外部的点击来关闭模式窗口:

module showmodal {
'use strict';

export class ShowModal implements ng.IDirective {
    restrict: string = 'A';
    scope: any = {
        showModal: '=showModal'
    };
    link: ng.IDirectiveLinkFn = (scope: ng.IScope, element: ng.IAugmentedJQuery, attributes: ng.IAttributes) => {
        function handler(): void {
            if ((element[0] !== event.target) && (0 === element.find(event.target).length)) {
                scope.$apply((): void => {
                    scope['showModal'] = false;
                });
            }
        }
        this.$document.on('click', handler);
        scope.$on('$destroy', () => {
            this.$document.off('click', handler);
        });
    };

    constructor(
        private $document: ng.IDocumentService,
        private $parse: ng.IParseService) {
    }

    static instance(): ng.IDirectiveFactory {
        const factory: ng.IDirectiveFactory = (
            $document: ng.IDocumentService,
            $parse: ng.IParseService): ng.IDirective => {
            return new ShowModal($document, $parse);
        };
        factory.$inject = [
            '$document',
            '$parse'
        ];
        return factory;
    }
}
angular.module('showmodal')
    .directive('showModal', ShowModal.instance());
}

实现为:

<div ng-init="showModal=false" show-modal="showModal">
    <input type="text" class="input" ng-click="showModal=!showModal" />
    <div class="modal" ng-show="showModal">The modal</div>
</div>

代码按预期工作。用户单击将 showModal 设置为 true 的输入,显示模态,当他们单击页面上的其他任何位置时,指令检测到单击,决定它是否在元素外部触发,如果是,则将 showModal 设置为 false,隐藏模态。

我正在尝试测试该指令。 Jasmine 测试不会触发 click 事件。这是我目前所拥有的:

module showmodal {
'use strict';

var element: ng.IAugmentedJQuery;
var scope: any;

describe('ShowModal directive', () => {
    beforeEach(() => {
        angular.mock.module('showmodal');
        angular.mock.inject(($rootScope: ng.IRootScopeService, $compile: ng.ICompileService) => {
            scope = $rootScope.$new();
            var html: ng.IAugmentedJQuery =
                angular.element('<div class="click" ng-click=""></div><div ng-init="showModal=false" show-modal="showModal"><input type="text" class="input" ng-click="showModal=!showModal" /><div class="modal" ng-show="showModal">The modal</div></div>');
            element = $compile(html)(scope);
            scope.$apply();
        });
    });
    iit('should set showModal to false', () => {
        expect(scope.showModal).toBeFalsy();
        element.find('.input').triggerHandler('click');
        scope.$apply();
        expect(scope.showModal).toBeTruthy();
        element.find('.click').triggerHandler('click'); <- element is clicked but does not fire the click event in the directive.
        scope.$apply();
        expect(scope.showModal).toBeFalsy(); <- fails here
    });
});
}

理论上,测试单击将 showModal 设置为 true 的输入(这有效)。然后它会单击类为“click”的 div,这应该会触发指令中的 click 事件,但它不会。

【问题讨论】:

    标签: javascript jquery html angularjs jasmine


    【解决方案1】:

    我自己通过点击 $document 而不是点击 div 解决了这个问题:

     var element: ng.IAugmentedJQuery;
    var scope: any;
    var document: ng.IDocumentService;
    
    describe('ShowModal directive', () => {
        beforeEach(() => {
            angular.mock.module('showmodal');
            angular.mock.inject((
                $rootScope: ng.IRootScopeService,
                $compile: ng.ICompileService,
                $document: ng.IDocumentService) => {
    
                document = $document;
                scope = $rootScope.$new();
                var html: ng.IAugmentedJQuery =
                    angular.element(
                        '<div ng-init="showModal=false" show-modal="showModal">' +
                        '<input type="text" class="input" ng-click="showModal=!showModal" />' +
                        '<div class="modal" ng-show="showModal">The modal</div>' +
                        '</div>');
                element = $compile(html)(scope);
                scope.$apply();
            });
        });
        it('should set showModal from false to true then back to false', () => {
            expect(scope.showModal).toBeFalsy();
            element.find('.input').triggerHandler('click');
            expect(scope.showModal).toBeTruthy();
            document.click();
            expect(scope.showModal).toBeFalsy();
        });
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-26
      • 1970-01-01
      • 1970-01-01
      • 2017-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多