Unit testing Angular directive click handler

陌路散爱 提交于 2019-12-12 05:30:43

问题


I've got a directive that adds a click handler to an element:

module.directive('toggleSection', ['$timeout', function ($timeout) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.bind('click', function (event) {
                scope.$apply(function () {
                    var scopeProp = 'show' + attrs.toggleSection;

                    event.preventDefault();
                    event.stopPropagation();

                    scope[scopeProp] = !scope[scopeProp];

                    return false;
                });

            });
        }
    };
}]);

When the element is clicked, it toggles another property on the scope, which another element is bound to with ng-show. It's working as it should in the app.

I've added the following test for the directive:

(function () {
    'use strict';

    // get the app module from Angular
    beforeEach(module('app'));

    describe('myCtrl', function () {

        var $scope, $rootScope;

        beforeEach(inject(function ($controller, _$rootScope_) {
            $scope = {};
            $controller('myCtrl', { $scope: $scope });
            $rootScope = _$rootScope_;
        }));

        describe('the toggleSection directive', function () {

            var testElement;

            beforeEach(function () {
                testElement = $compile('<a toggle-section="Test" href="#">Collapse section</a>')($rootScope);
                $rootScope.$digest();
            });

            it('inverts the value of the specified scope property', function () {
                $scope.showTest = false;
                testElement.click();

                expect($scope.showTest).toEqual(true);
            });

        });
    });

In the real code there are properties like $scope.showSection1 = false and by adding console logs in the directive I can see the properties before and after clicking the bound element and they have the expected values (e.g. the property starts as false and after you click the toggle element once it changes to true).

However, the test always fails with 'Expected false to equal true'. I think it's to do with the $apply method, because none of the show properties seem to exist on the scope when I run the test.

Other tests I have (even in the same spec file), which don't use the directive can see properties on the scope just fine.

What am I doing wrong?


回答1:


There are a few things to be changed in your test:

1 - scope creation should be changed from $scope = {} into $scope = $rootScope.$new();

2 - the directive should be compiled not into rootScope, but into scope

3 - the directive should first be created via angularjs.element and then compiled:

element = angular.element('<my-directive/>');
compile(element)(scope);
scope.$digest(); 


来源:https://stackoverflow.com/questions/32565101/unit-testing-angular-directive-click-handler

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!