AngularJS: Directive restrict : 'E' prevents element click() event being called in Jasmine unit test

Viewed 4120

Here are a couple of directives, and unit tests.

Here is the first directive:

directive('myTestDirective', function() {
    return {
        link: function(scope, element, attrs) {
            element.on("click", function(e) {
            scope.clicked = true;
            console.log("clicked");
        }
    }
});

And the unit test:

describe('my test directive', function() {
    beforeEach(function() {
        .....
        inject($compile, $rootScope) {
            scope = $rootScope.$new();
            html = '<div my-test-directive></div>';
            elem = angular.element(html);
            compiled = $compile(elem);
            compiled(scope);
            scope.$digest();
        }
    });
    it('should set clicked to true when click() is called', function() {
        elem[0].click();
        expect(scope.clicked).toBe(true);
    });
});

When the above unit test is run, the test passes and clicked is logged to the console.

However, consider this directive with restrict: E added:

directive('myDirective', function() {
    return {
        restrict: 'E',
        link: function(scope, element, attrs) {
            element.on("click", function(e) {
            scope.clicked = true;
            console.log("clicked");
        }
    }
});

And the unit test:

describe('my directive', function() {
    beforeEach(function() {
        .....
        inject($compile, $rootScope) {
            scope = $rootScope.$new();
            html = '<my-directive></my-directive>';
            elem = angular.element(html);
            compiled = $compile(elem);
            compiled(scope);
            scope.$digest();
        }
    });
    it('should set clicked to true when click() is called', function() {
        elem[0].click();
        expect(scope.clicked).toBe(true);
    });
});

This test fails. clicked is not logged to the console. From debugging I can see that the function bound the click() binding for the directive is not being executed.

How can I continue to use restrict : 'E', while still retaining the ability to simulate clicks in unit tests?

Update: I have it working, thanks to Michal's plunkr.

I changed the inject() function to be:

inject(function($compile, $rootScope, $document) {
    scope = $rootScope.$new();
    html = '<my-test-directive-element></my-test-directive-element>';
    elem = angular.element(html);
    $compile(elem)(scope);
    scope.$digest();
});

After this, both clicking using restrict attribute and restrict element work.

Plukr is here: http://plnkr.co/edit/fgcKrYUEyCJAyqc4jj7P

1 Answers
Related