Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit test failing when directive is an Attribute

I have a directive which is declared as an Attribute:

app.directive('myDirective', function() {
    return {
        restrict: 'A',
        replace: true,
        transclude: true,
        scope: {
            data: "="
        },
        template:
            '<p class="my-paragrapgh">' +
                '<label>Hello</label>' +
            '</p>'
    }
});

I have a unit test, which is failing:

describe('myDirective test', function () {
var scope, compile, element;

beforeEach(module('myModule'));

beforeEach(inject(function ($rootScope, $compile) {
    scope = $rootScope.$new();

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

it('should have a my-paragrapgh class', function () {
    expect($(element).find('p')[0]).toHaveClass('my-paragrapgh');
});

});

However, if i convert my diretive to an Element, and remove replace and transclude:

app.directive('myDirective', function() {
    return {
        restrict: 'E',
        //replace: true,
        //transclude: true,
        scope: {
            data: "="
        },
        template:
            '<p class="my-paragrapgh">' +
                '<label>Hello</label>' +
            '</p>'
    }
});

My unit test passes:

describe('myDirective test', function () {
var scope, compile, element;

beforeEach(module('myModule'));

beforeEach(inject(function ($rootScope, $compile) {
    scope = $rootScope.$new();

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

it('should have a my-paragrapgh class', function () {
    expect($(element).find('p')[0]).toHaveClass('my-paragrapgh');
});

});

How can i successfully test a directive declared as an Attribute? I'm using Karma, Jasmine and PhantomJS

like image 653
Oam Psy Avatar asked Dec 09 '25 17:12

Oam Psy


1 Answers

You will need to have an ng-transclude somewhere in your template when you have the transclude: true so that angular will know where to inject your HTML. Try:

app.directive('myDirective', function() {
    return {
        restrict: 'A',
        replace: true,
        transclude: true,

        scope: {
            data: "="
        },

        template:
            '<div ng-transclude><p class="my-paragrapgh">' +
                '<label>Hello</label>' +
            '</p></div>'
    }
});

Update

Looks like it's the replace option that could be causing the issue.

app.directive('myDirective', function() {
    return {
        restrict: 'A',

        scope: {
            data: "="
        },

        template:
            '<p class="my-paragrapgh">' +
                '<label>Hello</label>' +
            '</p>'
    }
});

With replace: true you're inner HTML is:

Fails

<label>Hello</label>

With replace undefined you have

Pass

<p class="my-paragrapgh"><label>Hello</label></p>
like image 93
Matt Herbstritt Avatar answered Dec 12 '25 06:12

Matt Herbstritt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!