我在测试指令时遇到依赖注入(理解)问题(只有在有待处理请求时才会显示AjaxLoader)。
应用声明:
angular.module('app', [
'directives.ajaxLoader',
'services.httpRequestTracker',
[...]
])
指令代码:
angular.module('directives.ajaxLoader', [])
.directive('ajaxLoader', ['httpRequestTracker',
function(httpRequestTracker) {
return {
templateUrl: 'common/ajaxLoader.tpl.html',
link: function($scope) { // This function can have more parameters after $scope, $element, $attrs, $controller
$scope.hasPendingRequests = function() {
return httpRequestTracker.hasPendingRequests();
};
}
};
}
])
测试代码:
describe('ajaxLoader', function() {
beforeEach(function() {
module('directives.ajaxLoader', 'common/ajaxLoader.tpl.html');
});
describe('ajaxLoader directive', function() {});
});
从那里开始,我的指令在浏览器中运行得非常好,但测试失败并出现如下错误:
错误:[$ injector:unpr]未知提供者:httpRequestTrackerProvider < - httpRequestTracker< - ajaxLoaderDirective
好的,所以我需要在某处注入我的依赖。我有两个解决方案:
angular.module('directives.ajaxLoader', [ 'services.httpRequestTracker' ])
beforeEach(function() { module('directives.ajaxLoader', 'common/ajaxLoader.tpl.html', 'services.httpRequestTracker'); });
两者都有效,但我不明白哪一个更好,为什么?为什么它从一开始就在我的浏览器中工作而在我的测试中失败?在这两种情况下,我的所有指令和跟踪器都在我的主应用声明中注入
由于
答案 0 :(得分:1)
加载模块
它适用于您的应用程序,因为已加载services.httpRequestTracker
。你通过将其声明为主应用程序模块(您的第一个代码段)的依赖项来实现这一点。
然而,当你测试时,你想要模拟未经测试的所有内容以避免biass。在您的情况下,如果您在services.httpRequestTracker
中遇到问题该怎么办? ajaxLoader
可能没问题但你的测试会失败。
<强>嘲讽强>
要模仿其他所有内容,您有两种选择:
要使用依赖项,您必须使用module()
加载模块。
你必须加载依赖项,但这可能有一个模拟实现。
依赖注入
依赖注入允许您解耦类。有一个服务定位器可以按名称解析依赖关系。也就是说,你说C类的属性a的类型是'animal'(一个字符串!)。角度核心中的服务定位器查找哪个组件实现它。确定这一点的方法是查找加载的模块(例如主应用程序模块的依赖关系)。
您没有在测试区域中定义任何此类内容(但这不是问题!)。 Karma使用包含要使用的文件列表的文件karma.conf
。您可以使用此文件添加库或模拟组件。
针对您的特定问题:
该指令取决于httpRequestTracker
。如果你不在那里注射它,它将无法工作(所以没关系)。
在您的测试中,您必须加载两者。这就是为什么第一次失败而第二次失败的原因。但是,我没有加载httpRequestTracker
,而是加载了它的模拟实现。