2015-06-23 17 views
27

Mam usługi w moim kątowej aplikacji, która wygląda mniej więcej tak:Jak przetestować funkcje „prywatny” w kątowym usługi z Karma i Jasmine

angular.module('BracketService', []).factory('BracketService', [function() { 
    function compareByWeight(a, b) { 
     return a.weight - b.weight; 
    } 
    function filterWeightGroup(competitors, lowWeight, highWeight) { 
     //filter stuff 
    } 
    function createBracketsByWeightGroup(weightGroup) { 
     //create some brackets 
    } 
    //set some base line values 
    var SUPER_HEAVY_WEIGHT = 500; 
    var SUPER_LIGHT_WEIGHT = 20; 
    return { 
     //create brackets from a list of competitors 
     returnBrackets: function(competitors) { 
      var brackets = {}; 
      //get super light weights 
      brackets.superLightWeights = createBracketsByWeightGroup(
       filterWeightGroup(competitors, 0, SUPER_LIGHT_WEIGHT) 
       .sort(compareByWeight) 
      ); 
      brackets.superHeavyWeights = createBracketsByWeightGroup(
       filterWeightGroup(competitors, SUPER_HEAVY_WEIGHT, Infinity) 
       .sort(compareByWeight) 
      ); 
      brackets.middleWeights = createBracketsByWeightGroup(
       filterWeightGroup(competitors, SUPER_LIGHT_WEIGHT, SUPER_HEAVY_WEIGHT) 
       .sort(compareByWeight) 
      ); 
      return brackets; 
     } 
    }; 

}]); 

chciałbym jednostka testowa nie tylko funkcje/właściwości, które są ujawnione w instrukcji return, ale także funkcje, które znajdują się poza instrukcją return.

Mój test jest obecnie skonfigurowana tak:

describe('BracketService', function() { 
    beforeEach(module('bracketManager')); 

    it('calling return brackets with no competitors will return 3 empty weight classes', inject(function(BracketService) { 
     var mockCompetitors = []; 
     var mockBracketResult = {superHeavyWeights: [[]], superLightWeights: [[]], middleWeights: [[]]}; 
     expect(BracketService.returnBrackets(mockCompetitors)).toEqual(mockBracketResult); 
    })); 
}); 

Ale jak mogę przetestować porównania, filtrowania i createBrackets funkcje, które nie są narażone przez instrukcji return?

Dzięki!

Odpowiedz

29

Nie ma sposobu na przetestowanie tych funkcji. Ich zakres jest funkcją, która obejmuje twoją fabrykę BracketService i są one niewidoczne w innym miejscu. Jeśli chcesz je przetestować, musisz je jakoś odsłonić.

Możesz przenieść je do własnej usługi (co wydaje się przesadą) lub możesz przetestować usługę BracketService za pomocą odpowiedniej ilości kombinacji danych, aby upewnić się, że funkcje wewnętrzne działają. To chyba najbardziej sensowne podejście.

Jeśli nie chcesz umieścić ich w osobnej usłudze, ale nadal czujesz potrzebę przetestowania tych funkcji wewnętrznych, po prostu zwróć je z fabryki wraz z zestawami zwracającymi.

Mogę to zrobić, gdy mam wiele funkcji pomocniczych, które można testować indywidualnie, ale otwierają kombinatoryczną skrzynkę Pandory na test czarnej skrzynki. Zazwyczaj takie funkcje poprzedzam znakiem "_", aby pokazać, że są one funkcjami pomocniczymi i są wystawione tylko na testowanie.

return { 
    //create brackets from a list of competitors 
    returnBrackets: function(competitors) {...}, 
    _filterWeightGroup: filterWeightGroup, 
    _createBracketsByWeightGroup: createBracketsByWeightGroup 
    }; 
11

Nie będzie można wywoływać tych funkcji bez ich ujawnienia. Ale, IMHO, prywatne metody nie powinny mieć testu jednostkowego, ale powinny być testowane w czasie testowania publicznej metody, która je wywołuje. To, co powinieneś zrobić, to kpić z przedmiotów, które otrzyma twoja prywatna funkcja, i będziesz w stanie spełnić ich oczekiwania.

3

Jedynym sposobem przetestowania ich w bieżącej konfiguracji jest przetestowanie zwróconej funkcji, ponieważ obecnie znajdują się one w zasięgu wewnątrz zakresu BracketService. Jeśli chcesz, aby były testowane indywidualnie, musisz je ujawnić w oświadczeniu zwrotnym jako właściwości BracketService.