我对Angular很新,并且已经回顾了Stack Overflow上所有类似相关的问题,但没有人帮助过我。我相信我已经正确设置了所有内容,但在尝试将服务注入单元测试时仍然出现“未知提供程序”错误。我在下面列出了我的代码 - 希望有人能发现一个明显的错误!
我在一个单独的 .js 文件中定义我的模块,如下所示:
angular.module('dashboard.services', []);
angular.module('dashboard.controllers', []);
这里我定义了一个名为EventingService的服务(为简洁起见,删除了逻辑):
angular.module('dashboard.services').factory('EventingService', [function () {
//Service logic here
}]);
这是我使用EventingService的控制器(这在运行时都可以正常工作):
angular.module('dashboard.controllers')
.controller('Browse', ['$scope', 'EventingService', function ($scope, eventing) {
//Controller logic here
}]);
这是我的单元测试 - 它是我尝试注入EventingService的行,当我运行单元测试时会导致错误:
describe('Browse Controller Tests.', function () {
beforeEach(function () {
module('dashboard.services');
module('dashboard.controllers');
});
var controller, scope, eventingService;
beforeEach(inject(function ($controller, $rootScope, EventingService) {
scope = $rootScope.$new();
eventingService = EventingService
controller = $controller('Browse', {
$scope: scope,
eventing: eventingService
});
}));
it('Expect True to be True', function () {
expect(true).toBe(true);
});
});
当我运行测试时,我收到此错误:
错误:未知提供者:EventingServiceProvider< - EventingService
我确保我的jasmine specrunner.html文件包含所有必需的源文件(这是一个Asp.Net MVC项目):
<!-- Include source files here... -->
@Scripts.Render("~/bundles/jquery")
<script type="text/javascript" src="@Url.Content("~/Scripts/angular.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/angular-mocks.js")"></script>
<script type="text/javascript" src="@Url.Content("~/App/scripts/app.js")"></script> <!-- Angular modules defined in here -->
<script type="text/javascript" src="@Url.Content("~/App/scripts/services/eventing.js")"></script> <!-- My Eventing service defined here -->
<script type="text/javascript" src="@Url.Content("~/App/scripts/controllers/browse.js")"></script> <!-- My Browse controller defined here -->
<!-- Include spec files here... -->
<script type="text/javascript" src="@Url.Content("~/App/tests/browse.js")"></script> <!-- The actual unit test here -->
我无法理解为什么Angular会抱怨我的EventingService这个错误。我的控制器在运行时工作正常 - 只是当我尝试测试它时我得到一个错误所以我很好奇我是否用模拟/注射搞砸了。
Angular对测试的帮助是垃圾,所以我目前感到难过 - 任何帮助或建议任何人都可以给予非常感谢。感谢。
答案 0 :(得分:25)
我刚刚遇到这个并通过切换到明确地使用$ injector获取服务来解决它:
var EventingService, $rootScope;
beforeEach(inject(function($injector) {
EventingService = $injector.get('EventingService');
$rootScope = $injector.get('$rootScope');
}));
我希望我能告诉你为什么这样做以及为什么简单
beforeEach(inject(function(EventingService) { .... }));
没有,但我没有时间调查内部。总是最好使用一种编码风格并坚持下去。
此样式更好,因为您在测试中使用的变量名称是服务的正确名称。但它有点冗长。
还有另一个角色魔法功能,它使用奇怪的变量名称,例如 $ rootScope ,但我不喜欢那种hacky外观。
请注意,大部分时间人们都会收到此错误,因为它们不包含模块:
beforeEach(module('capsuling'));
beforeEach(module('capsuling.capsules.services'));
答案 1 :(得分:6)
如果您的控制器(在dashboard.controllers
模块下定义)依赖于包含在不同模块(dashboard.services
)中的某些服务,而不是您需要在模块签名中引用依赖模块:
angular.module('dashboard.services', []);
angular.module('dashboard.controllers', ['dashboard.services']);
答案 2 :(得分:2)
虽然这个问题相当陈旧,但我却没有花费大量时间来解决与此问题类似的问题,即:
Error: Unknown provider: SomeServiceProvider <- SomeService
因此,我离开这里是另一个可能导致这个问题的原因。希望它对某人有帮助。
就我而言,我在我的项目中有两个名称完全相同但创建了不同依赖关系的模块,即两个不同的.js文件:
angular.module('moduleName', [dependencies]))
来自角度文档:
传递一个参数检索现有的angular.Module,而传递多个参数会创建一个新的angular.Module
结论:事实证明,测试中注入的内容是具有错误依赖关系的模块。从错误创建的模块中删除第二个参数解决了这个问题。
答案 3 :(得分:0)
您是否尝试过定义一个依赖于其他聚合模块的附加模块,如下所示:
angular.module( 'dashboard', [ 'dashboard.services', 'dashboard.controllers' ] )
所以你可以在beforeEach中指定一个模块,它同时定义了两个子模块:
describe('Browse Controller Tests.', function () {
beforeEach(function () {
module('dashboard');
});
var controller, scope, eventingService;
beforeEach(inject(function ($controller, $rootScope, EventingService) {
scope = $rootScope.$new();
eventingService = EventingService
controller = $controller('Browse', {
$scope: scope,
eventing: eventingService
});
}));
it('Expect True to be True', function () {
expect(true).toBe(true);
});
});