简体   繁体   中英

Unit test angular directive

So I am following along with the unit testing for a directive but I can't get it to compile...

directive

home.directive('myDirective', function($compile) {
    return {
        restrict: 'E',
        scope: {
            text: '@',
            href: '@'
        },
        link: function(scope, elem, attrs) {            
            var text = '<span>Text: <a href="'+scope.href+'">'+scope.text+'</a><br />';
            text += 'HREF: '+scope.href+'</span>';
            var newElement = $compile(text)(scope);            
            elem.replaceWith(newElement);
        }
    };
})

Test

describe( 'Test home controller', function() {
    beforeEach( module( 'home' ) );
    describe("myDirective", function() {    
        var $compile;
        beforeEach(inject(function(_$compile_, _$rootScope_){
            $compile = _$compile_;
            $rootScope = _$rootScope_;
        }));
        it ("Should transform my text", function() {
            element = $compile('<my-directive text="test text" href="http://yahoo.com"></my-directive>')($rootScope);
            $rootScope.$digest();
            console.log(element.text());
        });
    });
});

The console.log(element.text()) in my test spits out an empty string... I can get it to read the attributes... ie If I add expect(element.attr('text')).toBe("test text") it will pass but that obviosuly doesn't test my actual directive and isn't what i want to do.

Try rewriting your directive like so:

home.directive('myDirective', function($compile) {
    return {
        restrict: 'E',
        scope: {
            text: '@',
            link: '@'
        },
        template: '<p>Text: <a ng-href="{{link}}">{{text}}</a></p>',
        replace: true
    };
});

Then you can test like so:

describe( 'Test home controller', function() {
    beforeEach( module( 'home' ) );
    describe("myDirective", function() {    
        var $compile,
            $rootScope;
        beforeEach(inject(function(_$compile_, _$rootScope_){
            $compile = _$compile_;
            $rootScope = _$rootScope_;
        }));
        it ("Should transform my text", function() {
            element = $compile('<my-directive text="test text" link="http://yahoo.com"></my-directive>')($rootScope);
            $rootScope.$digest();
            console.log(element.text());
        });
    });
});

Updated - Second Approach

This updated approach demonstrates how you could use the link function along with $observe .

Try rewriting your directive like so:

home.directive('myDirective', function() {
    return {
        restrict: 'E',
        transclude: true,
        template: '<p>Text: <a ng-href="{{link}}">{{text}}</a></p>',
        link: function(scope, elm, attrs){
          attrs.$observe('text', function(newVal){
            scope.text = newVal + " tada";
          });
          attrs.$observe('link', function(newVal){
            scope.link = newVal + '/search?p=foo';
          });
        }
    };
});

Then you can test like so:

describe( 'Test home controller', function() {
    beforeEach( module( 'home' ) );
    describe("myDirective", function() {    
        var $compile;
        beforeEach(inject(function(_$compile_, _$rootScope_){
            $compile = _$compile_;
            $rootScope = _$rootScope_;
        }));
        it ("Should transform my text", function() {
            element = $compile('<my-directive text="test text" link="http://yahoo.com"></my-directive>')($rootScope);
            $rootScope.$digest();
            expect(element.text()).toBe('Text: test text tada');
        });
    });
});

Here is a working plunker

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM