3

我有一个指令,其中我试图写一些单元测试:如何向链路中测试功能

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(); 
    }); 

哪有我测试了getIndex,getData的呼叫并确保myService已被呼叫?

+0

不可能在不重构代码的情况下执行你所要求的操作。同样,可测试性原因应该定义代码的写法,反之亦然。测试不友好的代码不会获得100%的测试覆盖率(测试myService.getIndex调用是所有可以在这里完成的)。 – estus

回答

4

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

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

该元件,在规格编译之后,控制器实例可以被检索和与

var ctrl = element.controller('myDirective'); 
spyOn(ctrl, 'getIndex').and.callThrough(); 
窥探

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