测试指令链接功能,窥探$ watch?

时间:2015-03-19 21:18:32

标签: angularjs testing karma-jasmine

我对测试指令有疑问。

以下是我的指示

的副本
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()中提取值以确保它们得到适当的更新,但我还没有我想出来监视或确认我的链接函数中的各个分支执行并将正确的类应用于模板中的元素。

非常感谢任何指导。我觉得我一天中的大部分时间都在阅读这个主题,而且我仍在努力想出答案......

编辑:

我只是尝试将下面的元素附加到我的DOM的主体上,并且看起来看起来链接函数根本不适用于我的模板元素......不确定为什么。

编辑:

这是我的测试设置。我正在使用Karma和Jasmine:

    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(){

    });
});

由于

1 个答案:

答案 0 :(得分:0)

不要在link函数中使用jQuery。而是使用模板中的内置指令。例如:

<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>

然后在getClass中创建对应的getStyleisVisiblelink功能,这将更加强大和干净。

现在有一种测试方法,真正的答案是用Karma或Protractor测试套件来覆盖它,但是如果你想看看你的浏览器出了什么问题,你可以试试:< / p>

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

在你的$ watch中添加一些日志,例如console.log('New val is', val)