如何在指令链接中测试函数

时间:2016-03-02 16:49:07

标签: angularjs angularjs-directive jasmine karma-runner karma-jasmine

我有一个指令,我正在尝试编写一些单元测试:

return {
    restrict: 'E',
    replace: true,
    controllerAs: 'vm',
    transclude: true,
    template:   '<ul>' +
                    '<li ng-show="vm.hideItem">Home</li>' +
                    '<li ng-show="vm.hideItem">Products</li>' +
                    '<li ng-show="!vm.hideItem">Cart</li>' +
                    '<li ng-show="vm.hideItem">Contact Us</li>' +
                '</ul>',  
    link: function(scope, element, attrs, vm) {

        function getData(index) {
            if (index){
                vm.hideItem = true
            }
            else {
                var li = element.find("li");
                li.attr("context-driven", "");
            }
        }

        function getIndex(){
            index = myService.getIndex();
            getData(index);
        }

        getIndex();

    },
    controller: function(){}
};

我有以下内容,通过:

describe('<-- myDirective Spec ------>', function () {

    var scope, $compile, element, myService;

    beforeEach(angular.mock.module('MyApp'));

    beforeEach(inject(function (_$rootScope_, _$compile_, _myService_) {
        scope = _$rootScope_.$new();
        $compile = _$compile_;
        myService = _myService_;

        var html = '<my-directive></my-directive>';
        element = $compile(angular.element(html))(scope);
        scope.$digest();
    }));

    it('should return an unordered list', function () {
        var ul = element.find('ul');
        expect(ul).toBeDefined();
    });

如何测试getIndexgetData的来电并确保调用myService

1 个答案:

答案 0 :(得分:4)

成功指令测试的关键是将所有与视图相关的逻辑移动到控制器,即

    this.getIndex = function () {
        index = myService.getIndex();
        getData(index);
    }

在spec中编译元素后,可以使用

检索和监视控制器实例
var ctrl = element.controller('myDirective');
spyOn(ctrl, 'getIndex').and.callThrough();

编写规范的好处是它们显示出设计缺陷。在目前的情况下,它是getData中的DOM手动操作。从代码中不清楚context-driven属性的用途是什么,但是为了对测试友好,必须在Angular(数据绑定)而不是jQuery(DOM操作)方式中实现相同的目的。