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操作)方式必須實現相同的事情。