0

我在測試指令時出現了依賴注入(理解)問題(僅當存在未決請求時才顯示AjaxLoader)。瞭解應用程序中的注入依賴和AngularJS中的測試

應用程序聲明:

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

從那裏,我的指導工作得很好的瀏覽器,但試驗失敗出現如下錯誤:

Error: [$injector:unpr] Unknown provider: httpRequestTrackerProvider <- httpRequestTracker <- ajaxLoaderDirective

好吧,所以我需要在某處注入我的依賴項。我有兩個解決方案:

angular.module('directives.ajaxLoader', [ 
    'services.httpRequestTracker' 
]) 
    在我的測試代碼中直接
    • 在我的指令直接
    beforeEach(function() { 
        module('directives.ajaxLoader', 'common/ajaxLoader.tpl.html', 'services.httpRequestTracker'); 
    }); 
    

    這兩部作品,但我不瞭解哪一個更好以及爲什麼?爲什麼它從一開始就在我的瀏覽器中工作,並在我的測試中失敗?在這兩種情況下,我所有的指令和跟蹤在我的主要應用程序的聲明被注入

    感謝

回答

1

加載模塊

因爲services.httpRequestTracker加載它工作在你的應用程序。你通過將其聲明爲主應用程序模塊(您的第一個代碼片段)的依賴關係來實現此目的。

但是,當你測試的東西,你想嘲笑一切沒有被測試,以避免偏見。在你的情況下,如果你在services.httpRequestTracker有問題怎麼辦? ajaxLoader可能沒問題,但你的測試會失敗。

懲戒

到別的嘲笑一切,你有兩個選擇:

要使用依賴項,你必須加載模塊module()。您將不得不加載依賴項,但這可能有一個模擬實現。

依賴注入

依賴注入可以讓你脫鉤類。有一個服務定位器可以按名稱解析依賴關係。也就是說,你說屬性a的類C是'動物'類型(一個字符串!)。角度核心中的服務定位器查找哪個組件實現它。確定這種情況的一種方法是查找加載的模塊(例如,主應用模塊的依賴關係)。

你沒有在你的測試區域中定義任何這個(但它不是問題!)。 Karma使用包含要使用的文件列表的文件karma.conf。您可以使用此文件來添加庫或模擬組件。

有了您的具體問題:

該指令取決於httpRequestTracker。如果你不注入它,它將無法工作(所以它沒關係)。 在你的測試中,你必須同時加載。這就是爲什麼它第一次失敗,第二次失敗。但是,我不會加載httpRequestTracker,而是加載它的模擬實現。

+0

感謝您的詳細和啓發性的答案;)所以我的第一個解決方案'直接在我的指令'是完全禁止?我必須提供一個模擬或者在我的測試中明確地注入它? –

+1

嘿沒有概率!你應該考慮測試環境和應用程序,就像兩件事情一樣。關於應用程序:如果你需要在你的指令中注入某些東西,那就去做吧。如果你注入它,它應該被聲明爲模塊的依賴。現在,關於測試:如果你在你的指令中注入了(過去很簡單!)的東西,它應該被模擬或者提供模擬函數的答案。 –