簡體   English   中英

將服務注入Angular單元測試時出現Unknown Provider錯誤

[英]Getting Unknown Provider error when injecting a Service into an Angular unit test

我對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對測試的幫助是垃圾,所以我目前感到難過 - 任何人都可以給予任何幫助或建議將非常感激。 謝謝。

我剛剛遇到這個並通過切換到使用$ 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'));

如果您的控制器(在dashboard.controllers模塊下定義)依賴於包含在不同模塊( dashboard.services )中的某些服務,而不是您需要引用模塊簽名中的依賴項模塊:

angular.module('dashboard.services', []);
angular.module('dashboard.controllers', ['dashboard.services']);

雖然這個問題相當陳舊,但我在解決與此問題類似的問題時失去了大量時間,即:

Error: Unknown provider: SomeServiceProvider <- SomeService

因此,我將離開這里另一個可能的原因來解決這個問題。 希望它對某人有幫助。

在我的例子中,我在我的項目中有兩個模塊具有完全相同的名稱,但創建了不同的依賴項,即兩個不同的.js文件:

angular.module('moduleName', [dependencies]))

從角度文檔:

傳遞一個參數將檢索現有的angular.Module,而傳遞多個參數會創建一個新的angular.Module

結論 :事實證明,在測試中注入的是具有錯誤依賴性的模塊。 從錯誤創建的模塊中刪除第二個參數解決了該問題。

您是否嘗試過定義一個依賴於其他聚合模塊的附加模塊,如下所示:

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);
    });
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM