2013-09-22 25 views
1

我最近深入研究了單元測試。我想知道是否有辦法在生產代碼中使用間諜。我有一個跟蹤服務。能夠訪問其他服務甚至是控制器,而不必改變他們的代碼是很好的。在angularjs中的非測試代碼中使用間諜

有沒有辦法窺探從應用程序代碼中的服務和控制器調用的方法,以及最好的方法是什麼?

編輯 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 
       }, 

EDIT 2 我忘了補充迴歸到內在功能。

回答

1

應該沒有什麼能阻止你這樣做,儘管我認爲這是工作的錯誤工具。

如果你在Angular,你應該考慮使用裝飾模式。你甚至可以使用provider decorator來攔截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', []); 
}); 

這樣做會導致我的所有$http$compile功能打印到控制檯。

+0

謝謝提及。我完全忘了他們存在:) –

+0

但它並不真正我想要的。我不想以任何方式改變服務功能,我只想添加事件處理程序,在應用程序不同部分的特定操作,並且我想在單個分隔的位置執行跟蹤。 –

+0

我想我很困惑。裝飾者不會改變服務功能。它包裹着它們。然而,間諜會修改現有的服務。茉莉花間諜修改現有的服務,你提議的代碼也是如此。 –

相關問題