将服务注入Angular单元测试时出现Unknown Provider错误

Dud*_*Dud 32 testing mocking inject angularjs

我对Angular很新,并且已经回顾了Stack Overflow上所有类似相关的问题,但没有人帮助过我.我相信我已经正确设置了一切但在尝试将服务注入单元测试时仍然出现"未知提供商"错误.我在下面列出了我的代码 - 希望有人能发现一个明显的错误!

我在一个单独的.js文件中定义我的模块,如下所示:

angular.module('dashboard.services', []);
angular.module('dashboard.controllers', []);
Run Code Online (Sandbox Code Playgroud)

这里我定义了一个名为EventingService的服务(为简洁起见,删除了逻辑):

angular.module('dashboard.services').factory('EventingService', [function () {
    //Service logic here
}]);
Run Code Online (Sandbox Code Playgroud)

这是我使用EventingService的控制器(这在运行时都可以正常工作):

angular.module('dashboard.controllers')
    .controller('Browse', ['$scope', 'EventingService', function ($scope, eventing) {
        //Controller logic here
}]);
Run Code Online (Sandbox Code Playgroud)

这是我的单元测试 - 它是我尝试注入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);
    });
});
Run Code Online (Sandbox Code Playgroud)

当我运行测试时,我收到此错误:

错误:未知提供者: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 -->
Run Code Online (Sandbox Code Playgroud)

我只是无法理解为什么Angular会抛出这个错误抱怨我的EventingService.我的控制器在运行时运行良好 - 就在我尝试测试它时我得到了一个错误,所以我很好奇我是否用模拟/注入搞砸了.

Angular对测试的帮助是垃圾,所以我目前感到难过 - 任何人都可以给予任何帮助或建议将非常感激.谢谢.

fel*_*lix 27

我刚刚遇到这个并通过切换到使用$ injector显式获取服务来解决它:

var EventingService, $rootScope;
beforeEach(inject(function($injector) {
  EventingService = $injector.get('EventingService');
  $rootScope = $injector.get('$rootScope');
}));
Run Code Online (Sandbox Code Playgroud)

我希望我能告诉你为什么这个有用,为什么这么简单

beforeEach(inject(function(EventingService) {   ....  }));
Run Code Online (Sandbox Code Playgroud)

不,但我没有时间调查内部.总是最好使用一种编码风格并坚持下去.

这种样式更好,因为您在测试中使用的变量名称是服务的正确名称.但它有点冗长.

还有另一个角度魔术功能,使用奇怪的变量名称,如$ rootScope,但我不喜欢它的hacky外观.

请注意,大多数时候人们会收到此错误,因为它们不包含模块:

beforeEach(module('capsuling'));
beforeEach(module('capsuling.capsules.services'));
Run Code Online (Sandbox Code Playgroud)


Ste*_*wie 7

如果您的控制器(在dashboard.controllers模块下定义)依赖于一些服务,这些服务包含在不同的模块(dashboard.services)中,而不是您需要引用模块签名中的依赖模块:

angular.module('dashboard.services', []);
angular.module('dashboard.controllers', ['dashboard.services']);
Run Code Online (Sandbox Code Playgroud)

  • Stewie - 感谢您的回复,但我不认为这是问题所在.在我的应用程序中,我的依赖项工作正常(我的应用程序工作正常).这纯粹是我的测试,抛出这个错误,我相信我已经在我的'beforeEach'语句中加载了我测试的所有必需模块 (2认同)