如何使用Karma和Jasmine在角度服务中测试“私有”功能

时间:2015-06-23 20:53:57

标签: javascript angularjs unit-testing jasmine angular-services

我的角应用程序中有一项服务,看起来像这样:

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

}]);

我不仅要测试return语句中公开的函数/属性,还要测试return语句之外的函数。

我的测试目前设置如下:

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

但是如何测试return语句未公开的compare,filter和createBrackets函数?

谢谢!

3 个答案:

答案 0 :(得分:31)

无法测试这些功能。它们的范围是包含BracketService工厂的功能,它们在任何其他地方都是不可见的。如果你想测试它们,那么你必须以某种方式暴露它们。

您可以将它们移动到自己的服务中(这看起来有点矫枉过正),或者您可以使用足够的数据组合对您的BracketService服务进行黑盒测试,以确保内部功能正常工作。这可能是最明智的做法。

如果您不想将它们放在单独的服务中,但仍然觉得需要测试这些内部功能,只需将它们与returnBrackets一起从工厂返回。

当我有一些直接单独测试的辅助函数时,我可能会这样做,但打开一个组合的潘多拉盒子来进行黑盒测试。我通常使用" _"显示它们是辅助函数,仅用于测试。

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

答案 1 :(得分:13)

如果不以某种方式暴露这些功能,您将无法调用这些功能。但是,恕我直言,私有方法不应该有单元测试perse,但在测试它们的公共方法时进行测试。你应该做的是模仿你的私人功能将会收到的对象,你将能够对它们表现出期望。

答案 2 :(得分:3)

在当前设置中测试它们的唯一方法是测试返回的函数,因为它们当前位于BracketService内的范围内。如果您希望它们可单独测试,则需要在return语句中将它们作为BracketService的属性公开。