使用外部模板测试组件(angularjs> = 1.5)

时间:2017-10-04 13:48:25

标签: angularjs unit-testing karma-runner

我想使用外部模板测试组件。但每当我尝试在组件中找到元素时,我都无法获得任何结果。看起来组件是空的。

我加载模板的方式有什么问题,还是我正确编译组件?

项目结构:

libs/
app/
    arc/
        app.component.js
        app.module.js
        feature1/
            A.component.js
            A.component.spec.js
            A.controller.js
            A.html
        feature2/
            B.component.js
            B.component.spec.js
            B.controller.js
            B.html

karma.conf.js

//jshint strict: false
module.exports = function(config) {
  config.set({
    basePath: './src/app',
    frameworks: ['jasmine'],
    files: [
      '../../libs/angular/angular.js',
      '../../libs/angular-mocks/angular-mocks.js',
      '../../libs/angular-ui-router/release/angular-ui-router.js',
      '../../libs/angular-animate/angular-animate.js',
      '../../libs/angular-resource/angular-resource.js',
      '**/*.module.js',
      '**/*.spec.js',
      '**/*.html',
    ],

    preprocessors: {
      '**/*.html': ['ng-html2js'],
      '**/!(*.mock|*.spec).js': ['coverage']
    },

    ngHtml2JsPreprocessor: {
      // strip this from the file path
      ///stripPrefix: '',
      cacheIdFromPath: function(filepath) {
        let cacheId = filepath.split('/');
        return cacheId[ cacheId.length - 1 ];
      },
      // create a single module that contains templates from all the files
      moduleName: 'templates'
    },

    colors: true,

    autoWatch: true,

    browsers: ['Chrome'],

    reporters: ["spec"],

    specReporter: {
      maxLogLines: 5,             // limit number of lines logged per test 
      suppressErrorSummary: true, // do not print error summary 
      suppressFailed: false,      // do not print information about failed tests 
      suppressPassed: false,      // do not print information about passed tests 
      suppressSkipped: true,      // do not print information about skipped tests 
      showSpecTiming: false,      // print the time elapsed for each spec 
      failFast: true              // test would finish with error when a first fail occurs.  
    }

  });
};

A.html

<header> test </header>

A.component.js

var AComponent = {
  templateUrl: './A.html',
  controller: 'AController',
  bindings: {
  }
};

angular
  .module('app')
  .component('feature1', AComponent );

A.component.spec.js

'use strict';

describe('Component: AComponent', function () {
  beforeEach(module('app'));
  beforeEach(module('templates'));

  var element;
  var component;
  var scope;
  beforeEach(inject(function($rootScope, $compile){
    scope = $rootScope.$new();
    element = angular.element('<feature1> </feature1>');
    scope.$apply(function(){
      $compile(element)(scope);
    });
  }));

  it('should contain header element', function() {
    console.log( element.find('header').length )
  });

});

2 个答案:

答案 0 :(得分:2)

正如@StanislavKvitash所指出的,templateUrl必须与组件中定义的完全相同。在我的情况下,前导'./'导致在编译组件时无法解析模板。

为了解决这个问题,我刚刚在cacheIdFromPath方法中为所有结果添加了缺失的'./'。

ngHtml2JsPreprocessor: {
    cacheIdFromPath: function(htmlPath) {
      let cacheId = htmlPath.split('/');
      return './'+cacheId[ cacheId.length - 1 ];
    },
    // create a single module that contains templates from all the files
    moduleName: 'templates'
},

答案 1 :(得分:0)

好的,我想我可能有一个临时解决方案。

问题是,通过检查$templateCache,我实际上可以看到模板正确加载。然而,他们并没有被作为编译过程的一部分。因此,为了使其工作,我必须明确设置$compile()方法的模板。

这里的主要问题是,当模板名称发生变化时,我也必须更新规范文件。

'use strict';

describe('Component: AComponent', function () {
  beforeEach(module('app'));
  beforeEach(module('templates'));

  var element;
  var scope;
  beforeEach(inject(function($rootScope, $compile, $templateCache ){
    scope = $rootScope.$new();
    let template =  $templateCache.get('A.html');
    element = angular.element( '<feature1>'+template+'</feature1>' );
    scope.$apply(function(){
      $compile(element)(scope);
    });
  }));

  it('should contain header element', function() {
   var header = angular.element(element[0].querySelector('header'));
    expect(header.length).not.toBe(0);
  });

});