web-dev-qa-db-ja.com

KarmaとJasmineでangularサービスで「プライベート」機能をテストする方法

angularアプリに次のようなサービスがあります:

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関数をテストするにはどうすればよいですか?

ありがとう!

30
paniclater

これらの機能をテストする方法はありません。それらのスコープは、BracketServiceファクトリーを構成する関数であり、他の場所では見えません。それらをテストする場合は、何らかの方法で公開する必要があります。

それらを独自のサービスに移動する(やり過ぎのように見える)か、または内部機能が機能することを確認するのに十分なデータの組み合わせでBracketServiceサービスをブラックボックステストすることができます。それがおそらく最も賢明なアプローチです。

それらを別のサービスに入れたくないが、それらの内部関数をテストする必要性を感じている場合は、returnBracketsとともにそれらをファクトリから返すだけです。

個別にテストするのは簡単ですが、Pandoraのボックスからブラックボックスへの組み合わせテストを開くヘルパー関数がいくつかある場合、これを行うことができます。通常、このような関数の前に「_」を付けて、ヘルパー関数であり、テスト用にのみ公開されていることを示します。

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

何らかの方法で公開せずにこれらの関数を呼び出すことはできません。しかし、私見では、プライベートメソッドは単体テスト自体を持つべきではなく、それらを呼び出すパブリックメソッドがテストされるときにテストされるべきです。あなたがすべきことは、プライベート関数が受け取るオブジェクトをモックすることであり、それらに対して期待を実行できるようになります。

13
taxicala

現在の設定でそれらをテストする唯一の方法は、BracketService内のスコープに対して現在ローカルであるため、返された関数をテストすることです。それらを個別にテスト可能にする場合は、BracketServiceのプロパティとしてreturnステートメントで公開する必要があります。

3
Jan