1

我最近对单元测试进行了更深入的研究。我想知道是否有办法在生产代码中使用间谍。我有跟踪服务。无需更改代码即可访问其他服务甚至控制器会很好。

有没有办法监视从应用程序代码中的服务和控制器调用的方法,最好的方法是什么?

编辑 ATM。我正在使用这种模式来监视服务:

           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 中的几乎所有内容。

例如,您可能有一个如下所示的 spy 函数:

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', []); 
});

这样做会导致我的所有功能$http$compile功能都打印到控制台。

于 2013-09-23T00:19:33.643 回答