angularjs - 测试指令链接功能,监视 $watch?

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

    });
});

谢谢

最佳答案

不要在您的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>

然后在你的link中创建相应的getClass, getStyle, isVisible 函数,这样就更好了坚固而干净。

现在要找到一种测试方法,真正的答案是通过 Karma 或 Protractor 测试套件来覆盖它,但如果您想看看浏览器出了什么问题,您可以尝试:

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

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

关于angularjs - 测试指令链接功能,监视 $watch?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29155206/

相关文章:

android - 在不同设备上布局自动化测试

unit-testing - Karma 的基本目录位置

angular - 如何在 Angular Jasmine 规范中模拟路由器

javascript - 在 gulp 任务中使用 karma 获取报告

javascript - 使用 min.js 文件进行 angular.module 配置

javascript - Angular 核心指令

linux - 如何使用 GDB 创建测试脚本

android - 从不同的 Activity 开始 Espresso

javascript - 将对象 ID 传递到 session 存储

php - 如何从包含angularjs中json数组的json对象中获取特定值