2015-03-19 2 views
1

У меня вопрос по тестированию директивы.

Вот копия моей директивы

angular.module('dashboard').directive('gradientBar', function() { 
return { 
    restrict: 'E', 
    template: '<div class="bar"><div id="change_arrow"></div><div class="bar-fill"></div><div class="bar-ref"></div></div>', 
    replace: true, 
    scope: { 
     'min': '=', 
     'max': '=', 
     'val': '=', 
     'avg': '=', 
     'prev': '=', 
    }, 

    link: function(scope, element, attrs) { 
     scope.$watch('val', function() { 

      var ref_current = Math.round((scope.val - scope.min) * 100/(scope.max - scope.min)); 

      if (scope.prev) { 

       var ref_prev = Math.round((scope.prev - scope.min) * 100/(scope.max - scope.min)); 
       if (ref_current - ref_prev >= 1) { 

        element.find('#change_arrow').addClass('expand-button up_dark'); 
        element.find('.bar-ref').css('left', ref_prev + "%"); 

       } else if (ref_current - ref_prev <= -1){ 
        element.find('#change_arrow').addClass('expand-button down_dark'); 
        element.find('.bar-ref').css('left', ref_prev + "%"); 
       } else { 
        element.find('.bar-ref').css('display', 'none'); 
       } 

      } else if (scope.avg) { 
       var ref_avg = Math.round((scope.avg - scope.min) * 100/(scope.max - scope.min)); 
       element.find('.bar-ref').css('left', ref_avg + "%"); 

      } else { 
       element.find('.bar-ref').css('display', 'none'); 
      } 

      var width = (scope.val - scope.min)/(scope.max - scope.min); 
      element.find('.bar-fill').css('width', ref_current + "%").css('background', colorify(width)); 

     }); 
    } 

Я пытаюсь выяснить, лучший способ проверить функцию линии связи в этой директиве ... Я понял, как вывести значения в isolateScope(), чтобы убедиться, что они обновлены соответствующим образом, но я не понял, чтобы следить или подтвердить, что различные ветви в моей функции ссылок выполняются и применяют правильные классы к элементам в Шаблоне.

Любое руководство будет очень оценено. Я чувствую, что я читал на эту тему в течение большей части дня, и я до сих пор пытаюсь выяснить ответ ...

EDIT:

Я просто попытался добавить элемент ниже в тело моего DOM, и это не похоже на то, что функция ссылки была применена вообще к моему элементу шаблона ... неуверенность в том, почему.

EDIT:

Вот моя тестовая установка. Я использую Карму и Жасмин:

describe('gradientBar.js Unit Tests', function(){ 
    var $compile, scope, element, isolatedScope; 

    beforeEach(module('dashboard')); //the module of the file under test 

    beforeEach(module('partialsCacheHaml')); 

     // scope.$digest(); 
    beforeEach(inject(function (_$rootScope_, _$compile_) { 

     $compile = _$compile_; 
     scope = _$rootScope_; 

     elementT = angular.element('<gradient_bar min="min" max="max" val="val" prev="prev" avg="avg"></gradient_bar>'); 

     scope.min = 0; 
     scope.max = 4; 
     scope.val = 2; 
     scope.prev = false; 
     scope.avg = false; 
     scope.should_not_be_accessible_in_isolated_scope = '111'; 

     element = $compile(elementT)(scope); 

     spyOn(element, 'find') 

     isolatedScope = element.isolateScope(); 

     scope.$digest(); 

    })); 

    it(' IsolatedScope contains the appropriate bindings', function(){ 

     expect(isolatedScope.min).toBe(0); 
     expect(isolatedScope.max).toBe(4); 
     expect(isolatedScope.val).toBe(2); 
     expect(isolatedScope.prev).toBe(false); 
     expect(isolatedScope.avg).toBe(false); 
     expect(isolatedScope.should_not_be_accessible_in_isolated_scope).toBe(undefined); 

    }); 

    it(' After compilation, element contains the appropriate html tags', function(){ 

     expect(element.html()).toContain('<div id="change_arrow"></div>'); 
     expect(element.html()).toContain('<div class="bar-fill"></div>'); 
     expect(element.html()).toContain('<div class="bar-ref"></div>'); 

    }); 

    it(' updates rootScope when values in isolatedScope are updated', function(){ 
     //this is due to the '='' declaration in the isolated scope of the directive 
     isolatedScope.min = 20; 
     isolatedScope.max = 20; 
     isolatedScope.val = 20; 
     isolatedScope.prev = 20; 
     isolatedScope.avg = 20; 

     isolatedScope.$digest(); 
     expect(isolatedScope.min).toBe(20); 
     expect(scope.min).toBe(20); 
     expect(isolatedScope.max).toBe(20); 
     expect(scope.max).toBe(20);  
     expect(isolatedScope.val).toBe(20); 
     expect(scope.val).toBe(20);  
     expect(isolatedScope.prev).toBe(20); 
     expect(scope.prev).toBe(20);   
     expect(isolatedScope.avg).toBe(20); 
     expect(scope.avg).toBe(20); 
    }); 

    it(' sets the .bar-fill width parameter to the %away from the difference between min and max of val', function(){ 

     var val_param = Math.round((isolatedScope.val - isolatedScope.min) * 100/(isolatedScope.max - isolatedScope.min)); 

    }) 

    it(' adds the expand-button up_dark class to #change_arrow when the percentage difference between val and prev is greater than 1', function(){ 

    }); 

    it(' adds the expand-button down_dark class to #change_arrow when the percentage difference between val and prev is less than -1', function(){ 

    }); 

    it(' adds the left = xx% value to the .bar-ref div if prev does not exist (is false) and avg exists', function(){ 

    }); 

    it(' adds the display=none property to the .bar-ref div if prev does not exist and avg does not exist', function(){ 

    }); 
}); 

Благодаря

ответ

0

Не использовать JQuery в вашей link функции. Вместо этого используйте встроенные директивы в своем шаблоне. Например такие вещи, как:

<div class="bar"> 
    <div class="bar-arrow" ng-class="getClass()"></div> 
    <div class="bar-fill" ng-style="getStyle()"></div> 
    <div class="bar-ref" ng-show="isVisible()"></div> 
</div> 

, а затем создать correspoding getClass, getStyle, isVisible fucntions в вашем link, что было бы более надежным и чистым.

Теперь способ проверить, что реальный ответ будет, чтобы покрыть его кармой или транспортир тестовых наборов, но если вы хотите, чтобы взглянуть на то, что случилось с вашего браузера, вы можете попробовать:

var elem = $('.bar') // get the directive root element 
var scope = elem.isolateScope(); 
scope.val = 42; 
scope.$digest(); 

И в ваших $ watch добавить несколько журналов, таких как console.log('New val is', val).

+0

Я использую карму/Жасмин для тестирования. Здесь я хочу написать свои тесты, что функция ссылки работает так, как ожидалось, и мой элемент получает правильные классы, применяемые к ней (по логике в функции ссылок). в моих тестах, однако, после i element = $ compile () (scope), если я console.log (элемент), то html совпадает с шаблоном директивы, который я передаю, чтобы скомпилироваться/связанный. Я пытаюсь увидеть, как выглядит HTML после выполнения функции ссылки. Любой совет? – jjt143

+0

Вы уверены, что передали параметр «val»? Обязательно примените свой объем в тесте и потенциально добавьте тайм-аут, прежде чем проверять скомпилированный HTML. Я не очень хорошо знаком с кармой, поэтому не уверен, как она обрабатывает цикл действия. И если вы этого не сделаете, я должен сначала проверить директиву непосредственно в браузере самостоятельно, а затем написать регрессионный тест, чтобы убедиться, что он продолжает это делать. Но легче проверить эту директиву, если на ней будет быстро зависеть. – floribon

+0

Да, директива работает так, как я ожидаю в браузере ... эти тесты предназначены только для обеспечения хорошего охвата. Я уверен, что прохожу мимо. У меня есть несколько тестов, которые проверяют, что моя изолированная область обновляется соответствующим образом. – jjt143