2014-11-25 87 views
7

我測試自定義AngularJS指令使用Karma + Jasmine和ngHtml2JsPreprocessor插件爲了服務我的指令模板,但我不明白爲什麼我的指令似乎無法訪問模板(編譯元素爲空)。 我定義在該指令templateUrl這樣:AngularJS測試指令與Karma,Jasmine和ngHtml2JsPreprocessor:模板未加載

templateUrl: 'templates/angular/mywidget.html' 

我噶配置如下(它的相關部分):

 basePath: '../../main/webapp/static/', 
     files: [ 
      {pattern: 'libs/angular/angular.js', watch: false}, 
      {pattern: 'libs/angular-resource/angular-resource.js', watch: false}, 
      {pattern: 'libs/angular-mocks/angular-mocks.js', watch: false}, 
      {pattern: 'libs/angular-ngkit/js/ngkit.js', watch: false}, 
      {pattern: 'libs/jquery/dist/jquery.js', watch: false}, 
      'templates/angular/*.html', 
      'js/angular/**/*.js', 
      '../../../test/js/spec/angular/*.js' 
     ], 
     preprocessors: { 
      'templates/angular/*.html': ['ng-html2js'] 
     }, 
     ngHtml2JsPreprocessor: { 
      moduleName: 'templates' 
     }, 
     browsers: [ 
      'PhantomJS' 
     ], 
     plugins: [ 
      'karma-phantomjs-launcher', 
      'karma-jasmine', 
      'karma-ng-html2js-preprocessor' 
     ], 

,並在我的測試:

beforeEach(module('templates')); 
beforeEach(module('ngResource')); 
beforeEach(module('mywidget')); 

「有趣」的部分是,如果我測試模板緩存,模板會被加載和編譯:

beforeEach(inject(function(_$templateCache_) { 
    var template = _$templateCache_.get('templates/angular/mywidget.html'); 
})); 

模板存在!爲什麼我的指令不能使用它? (在瀏覽器中它可以很好地工作)。 如果我在我的指令中將templateUrl替換爲inline template,它會在測試中正確呈現......但我必須使用外部模板,不能將其置於內聯中......我被卡住了!任何聰明的想法?

UPDATE(我試過到目前爲止):

  1. 寫出沒有邏輯了新指令(排除該問題是在執行),簡單地說:

    angular.module('modulename', []). directive('foo', function() { return { templateUrl: 'path/to/template.html' } });

  2. 簡化模板內容:

    <div>hello world</div>

  3. 改變模板路徑

  4. 改變模板名稱

  5. 變化因緣配置文件的位置

  6. 刪除多餘的依賴關係,如 「ngResource」 和類似

  7. 重新安裝所有的bower依賴關係(並清理緩存)

  8. 重新安裝所有的NPM包命令行

  9. 搗我用拳頭砸向桌子(我在的IntelliJ IDEA使用噶插件運行測試),而投擲褻瀆的斐波那契序列

  10. 運行測試如果他聽了,就會殺死教皇!

(最新的一個通常帶我去解決方案...但這次不行)

更新2:

我通過這種方式確定我的指令繞過這個問題:

directive('mywidget', function($templateCache) { 
     var config = {}; // directive definition (where you define "link", "restrict"...) 
     var templateUrl = 'templates/angular/mywidget.html'; 
     var cachedTemplate = $templateCache.get(templateUrl); 
     if (cache) { 
      config.template = cachedTemplate; 
     } 
     else { 
      config.templateUrl = templateUrl; 
     } 
     return config; 
}); 

通過使用這一招,我的指令得到測試正確呈現。 這一點聽起來AngularJS中的一個錯誤...它以某種方式從緩存中加載模板失敗。 我真的很失望:(

+0

我有同樣的問題,但在我的情況下,修復很簡單:調用'$ compile()'後調用'scope。$ apply()',否則模板沒有機會加載。 – 2015-03-12 15:39:09

回答

4

YEAAAAAAAAAAH! 我終於解決了這個瘋狂的問題!!! 問題是我正在使用不同版本的角度依賴(角度嘲笑,角度資源...)事實證明,如果你正在使用,讓我們說,角1.2.27 , 然後你必須也一定要使用角度嘲笑1.2.27,角度資源1.2.27等,否則可能會有像我遇到的衝突。 當然,這不是我的意圖,使用不同的版本,但通過鮑爾安裝我的依賴關係,我得到這些庫「unaligned」。

1

嘗試追加編譯元素添加到文檔體

angular.element(document.body).append(element); 

你可以把它放在一個beforeEach塊:

beforeEach(function() { 
    inject(function(_$compile_, _$rootScope_) { 
    var compile, element, rootScope, scope; 
    compile = _$compile_; 
    rootScope = _$rootScope_; 
    scope = rootScope; 
    element = angular.element('<hello-directive></hello-directive>'); 
    compile(element)(scope); 
    angular.element(document.body).append(element); 
    scope.$apply(); 
    }); 
}); 
+0

不,這不是問題,元素應該包含渲染的指令,並獨立於節點所在的位置! (無論如何,我已經將標籤注入dom中)...我認爲問題不在測試套件中,而是與測試環境相關(可能是插件的某種「衝突」/「競爭條件」) – daveoncode 2014-11-26 08:25:43

相關問題