Search code examples
angularjsdirectivetestcase

How to test directive by writing test case?


recently I am trying to write the test case for directive.

For example, this is a directive to manupulate the DOM in browser.

var demoApp = module('demoApp', ['']);
demoApp.directive('tabTo', function(){
    var linkFunc = function(scope, element, attrs, controllers){
        element.bind('keyup', function(e){
            var maxLength = attrs['maxlength'] || attrs['ng-maxlength'];
            if(maxLength && this.value.length === length){
                var tabTarget = angular.element.find('#' + attrs['tab-to']);
                if(tabTarget){
                    tabTarget.focus();
                }
            }          

        }
    } 
    return {
        restrict: 'A',
        link: linkFunc      
    }       

 });

Then I implemented the test case here:

describe('Unit testing great quotes', function() {
    var $compile;
    var $rootScope;

    beforeEach(module('myAppdemoApp'));
    beforeEach(inject(function(_$compile_, _$rootScope_){

        $compile = _$compile_;
        $rootScope = _$rootScope_;
    }));

    it('Replaces the element with the appropriate content', function() {
        var element = $compile('<input type="text" maxlength="8" id="input1" tab-to="input2" /><input type="text" id="input2" maxlength="8" tab-to="input3"/> <input type="text" id="input3" max-length="8" />')($rootScope);
        element.appendTo(document.body); //appendTo to document so that in directive can find it by 'angular.element.find()'
        $rootScope.$digest();

        var tmpInputs = angular.element.find('#input1');
        var input1 = tmpInputs[0];

        tmpInputs = angular.element.find('#input2');
        var input2 = tmpInputs[0];

        spyOn(input2, 'focus');

        input1.val('12345678');
        input1.keyup();

        expect(input2.focus).haveBeenCalled();

    });
});

My question is, is it the proper way to write the test case ? Cuz' I'm don't know too much about the unit test. I just talked with my colleague, and he told me that this looks like End-to-End test. So is it that means to test directive we have to write the End-to-End test?

Could anybody help me ? Thx a lot...


Solution

  • your directive manipulates DOM (focus, bind). so in your tests you can simply check if DOM has changed in expected way. you don't need end to end tests. i would say your test is a little bit too big. i think you don't need spyOn and appendTo, just:

    1. use $compile to build DOM with your directive
    2. change properties of scope and/or DOM to trigger expected directive behavior
    3. trigger angular (e.g scope.$apply())
    4. verify the DOM

    you can find sample here: http://blog.piotrturski.net/2014/11/nesting-angular-directives.html