我最近对单元测试进行了更深入的研究。我想知道是否有一种方法可以在生产代码中使用 spy 。我有跟踪服务。如果无需更改代码即可访问其他服务甚至 Controller ,那就太好了。
有没有办法监视应用程序代码中的服务和 Controller 调用的方法,最好的方法是什么?
编辑 自动取款机。我使用此模式来监视服务:
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 我忘记在内部函数中添加返回。
最佳答案
应该没有什么可以阻止你这样做,尽管我认为这是不适合这项工作的工具。
如果您使用 Angular,您应该考虑使用装饰器模式。您甚至可以使用 provider decorator拦截 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);
});
}
您可以像这样配置您的 spy :
app.config(function($provide) {
decorateWithSpy($provide, '$http', ['get']);
decorateWithSpy($provide, '$compile', []);
});
这样做会导致我的所有 $http
和 $compile
函数打印到控制台。
关于javascript - 在 angularjs 中的非测试代码中使用 spy ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18948777/