1

私は最近、単体テストをもう少し深く掘り下げました。プロダクションコードでもスパイを使用する方法があるかどうか疑問に思っていました. 追跡サービスをしています。コードを変更することなく、他のサービスやコントローラーにアクセスできると便利です。

アプリケーションコードでサービスとコントローラーから呼び出されているメソッドをスパイする方法はありますか?そのための最良の方法は何ですか?

大気編集 私はサービスをスパイするためにこのパターンを使用しています:

           var vSetFNTrigger = function (sEvent, fnTrigger) {
                fnTrigger.obj[fnTrigger.sMethod] = (function () {
                    var fnCached = fnTrigger.obj[fnTrigger.sMethod];
                    return function () {
                        $rootScope.$broadcast(sEvent, {});
                        return fnCached.apply(this, arguments);                            
                    };
                })(); 
            };
                fnTrigger: {
                    obj: formData, // the service
                    sMethod: 'qPost' // the method to spy on
                },

編集 2 内部関数に戻り値を追加するのを忘れていました。

4

1 に答える 1

1

これは仕事には不適切なツールだと思いますが、これを行うことを妨げるものは何もないはずです。

Angular を使用している場合は、デコレータ パターンの使用を検討する必要があります。プロバイダ デコレータを使用して、Angular のほとんどすべてをインターセプトすることもできます。

たとえば、次のようなスパイ機能があるとします。

function createSpy(serviceName, source, spyNames, rootScope) {
    var spy = angular.extend(angular.isFunction(source) ? function () {
        console.log("Called " + serviceName + '()', arguments);
        // broadcast with rootScope
        return source.apply(source, arguments);
    } : {}, source);

    spyNames.forEach(function(name) {
        var original = spy[name];
        spy[name] = function() {
            console.log("Called " + serviceName + '.' + name, arguments);
            // broadcast with rootScope
            return original.apply(spy, arguments);
        };
    });

    return spy;
}

次に、デコレータを生成する汎用関数を作成できます。

function decorateWithSpy($provide, service, spyNames) {
    $provide.decorator(service, function($delegate, $rootScope) {
        return createSpy(service, $delegate, spyNames, $rootScope);
    });
}

次のようにスパイを構成できます。

app.config(function($provide) {
    decorateWithSpy($provide, '$http', ['get']);
    decorateWithSpy($provide, '$compile', []); 
});

これを行うと、すべての my$httpおよび$compile関数がコンソールに出力されます。

于 2013-09-23T00:19:33.643 に答える