单元测试AngularJS文档就绪函数

时间:2015-05-20 18:07:49

标签: javascript jquery angularjs unit-testing

我正在编写一个AngularJS应用程序,而我正在寻找一种对每个方面进行单元测试的方法。

在这种特殊情况下,我需要对我编写的代表控件的自定义指令进行单元测试。

该指令可在此处找到:

var officeButton = angular.module('OfficeButton', []);

officeButton.directive('officeButton', function() {
    return {
        restrict: 'E',
        replace: false,
        scope: {
            isDefault: '@',
            isDisabled: '@',
            control: '=',
            label: '@'
        },
        template: '<div class="button-wrapper" data-ng-click="onClick()">' +
                    '<a href="#" class="button normal-button">' +
                      '<span>{{label}}</span>' +
                    '</a>' +
                  '</div>',
        controller: ['$scope', function($scope) {
            var event = this;

            var api = {

                changeLabel: function(label) {
                    $scope.label = label;
                },

                enable: function() {
                    $scope.isDisabled = false;
                },

                disable: function() {
                    $scope.isDisabled = true;
                },

                setAsDefault: function() {
                    $scope.isDefault = true;
                },

                removeDefault: function() {
                    $scope.isDefault = false;
                }
            };

            event.onClick = function() {
                if (typeof $scope.control.onClick === 'function') { $scope.control.onClick(); }
            };

            $.extend($scope.control, api);

            function Init() {
                if ($scope.isDefault === 'true') { $scope.isDefault = true; }
                else { $scope.isDefault = false; }
            }

            Init();
        }],

        link: function(scope, element, attributes, controller) {

            scope.$watch('isDefault', function(value) {
                if (value === 'true' || value) { $('a', element).addClass('button-default'); }
                else { $('a', element).removeClass('button-default'); }
            });

            scope.onClick = function() { controller.onClick(); }
        }
    }
});

可以使用以下HTML代码段调用此指令:

<office-button label="Office Web Controls" control="buttonController"></office-button>

现在,该指令公开了一个API,其功能包括changeLabelenabledisable,....

现在,这些函数没有在应用程序的加载中定义,这意味着如果在我的HTML底部我调用以下代码:

$ scope.buttonController.changeLabel('用于Web应用程序的Office Web控件指令演示');

由于未定义changeLabel()方法,因此会抛出错误。

为了使其起作用,我需要将这些调用包装在angular.ready函数中,例如:

angular.element(document).ready(function () {
    $scope.buttonController.changeLabel('Office Web Controls for Web Applications Directive Demo');
});

以下是plunker,供您参考。

现在,我正在使用Jasmine编写单元测试,这就是我现在所拥有的:

describe('Office Web Controls for Web Applications - Button Testing.', function() {
    // Provides all the required variables to perform Unit Testing against the 'button' directive.
    var $scope, element;
    var buttonController = {};

    // Loads the directive 'OfficeButton' before every test is being executed.
    beforeEach(module('OfficeButton'));

    // Build the element so that it can be called.
    beforeEach(inject(function($rootScope, $compile) {
        // Sets the $scope variable so that it can be used in the future.
        $scope = $rootScope;
        $scope.control = buttonController;

        element = angular.element('<office-button control="buttonController"></office-button>');
        $compile(element)($scope);
        $scope.$digest();
    }));

    it('Should expose an API with certain functions.', function() {
    });
});

现在,在it函数中,我想测试$scope.control是否确实公开了指令中定义的API。

问题是在API可用之前页面需要准备就绪。

是否有任何关于如何更改代码或如何正确单元测试?

1 个答案:

答案 0 :(得分:0)

我发现了这个问题,单元测试只是一个错误的配置。

使用此代码时:

$scope.control = buttonController;
element = angular.element('<office-button control="buttonController"></office-button>');

我必须将元素更改为:

$scope.control = buttonController;
element = angular.element('<office-button control="control"></office-button>');