web-dev-qa-db-fra.com

Comment tester des fonctions «privées» dans un service angular avec Karma et Jasmine

J'ai un service dans mon angular qui ressemble à ceci:

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

}]);

Je voudrais tester unitairement non seulement les fonctions/propriétés qui sont exposées dans l'instruction de retour, mais aussi les fonctions qui sont en dehors de l'instruction de retour.

Mon test est actuellement configuré comme ceci:

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

Mais comment puis-je tester les fonctions de comparaison, de filtrage et de création de supports qui ne sont pas exposées par l'instruction return?

Merci!

30
paniclater

Il n'y a aucun moyen de tester ces fonctions. Leur portée est la fonction qui comprend votre usine BracketService et ils sont invisibles ailleurs. Si vous voulez les tester, vous devez les exposer d'une manière ou d'une autre.

Vous pouvez les déplacer dans leur propre service (ce qui semble exagéré) ou vous pouvez tester la boîte noire de votre service BracketService avec suffisamment de combinaisons de données pour vous assurer que les fonctions internes fonctionnent. C'est probablement l'approche la plus sensée.

Si vous ne voulez pas les mettre dans un service séparé, mais ressentez toujours le besoin de tester ces fonctions internes, renvoyez-les simplement de l'usine avec returnBrackets.

Je pourrais le faire lorsque j'ai un certain nombre de fonctions d'assistance qui sont simples à tester individuellement, mais ouvrent un test combinatoire de boîte de Pandore à boîte noire. Je préfère généralement ces fonctions avec un "_" pour montrer qu'elles sont des fonctions d'assistance et ne sont exposées que pour les tests.

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

Vous ne pourrez pas appeler ces fonctions sans les exposer d'une manière ou d'une autre. Mais, à mon humble avis, les méthodes privées ne devraient pas avoir de perse de test unitaire, mais être testées au moment où la méthode publique qui les appelle est testée. Ce que vous devez faire, c'est vous moquer des objets que votre fonction privée recevra et vous pourrez y répondre.

13
taxicala

La seule façon de les tester dans votre configuration actuelle est de tester la fonction retournée car elles sont actuellement locales à la portée à l'intérieur de BracketService. Si vous souhaitez qu'ils puissent être testés individuellement, vous devrez les exposer dans l'instruction return en tant que propriétés de BracketService.

3
Jan