Angular.js 使用 html2js 将指令与外部模板联合起来 - 无法加载模板

我正在尝试测试使用外部模板的指令.我尝试了以下所有解决方案,但没有成功:

I am trying to test a Directive which uses external template. I tried all the following solutions with no luck:

  • ng-directive-testing

如何测试使用 templateUrl 和控制器?

AngularJS + Karma + Ng-html2js =>无法实例化模块...html

我创建了一个测试指令(一个简单的 div)并使用内联模板"和外部模板Url"对其进行了测试.内联解决方案有效,而外部无效:

I created a test directive (a simple div) and tested it using an inline 'template' and external 'templateUrl'. The inline solution works while the external doesn't:

   angular.module('AdUnit').directive('actionButton',function($location){
        return{
            scope:{
                actionName: '@'
            },
            restrict: 'E',
            //template: "<div ng-click='click()'>action button</div>",
            templateUrl: '/staticfiles/adunit/html/directives/actionButtonTemplate.html',
            controller: ['$scope', function($scope){
                $scope.click = function(){
                    $scope.$emit('ACTION_CLICK', $scope.actionName);
                }
            }]

        }
    });



    describe("Unit: Testing action button directive", function() {
    var elm, scope, linkFn;
    beforeEach(
        module('AdUnit')
    );

    beforeEach(module('/staticfiles/adunit/html/directives/actionButtonTemplate.html'));

    beforeEach(inject(function($rootScope, $compile) {
        elm = angular.element('<action-button action-name="post-action-0"></action-button>');
        scope = $rootScope;
        linkFn = $compile(elm);
        linkFn(scope);
        scope.$digest(); // have to digest to bring html from templateCache
        console.log('post compile',elm.html());// <== the html here still have {{}}
    }));

    it('should show a thumb',function() {

            console.log('post link',elm.html());// <== the html is bound

            expect(elm.text()).toBe("action button");

    });
});

我的 Karma 配置文件:

My Karma config file:

  module.exports = function(config) {
  config.set({

    // base path, that will be used to resolve files and exclude
    basePath: '',


    // frameworks to use
    frameworks: ['jasmine'],


    // list of files / patterns to load in the browser
    files: [
        'http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js',
        'http://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular.min.js',
        'http://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular-route.js',
        'http://code.angularjs.org/1.0.6/angular-mocks.js',
        '../html/*.html',
        '../html/directives/*.html',
        '../js/adUnit.js',
        '../js/controllers/*.js',
        '../js/directives/*.js',
        '../js/services/*.js',
        '../*.js',
         '../**.*.js',
         '**/*.tests.js'
    ],

    preprocessors : {
        '../html/**/*.html': ['ng-html2js']
    },

     /* ngHtml2JsPreprocessor: {
          'AdUnit': '/staticfiles/adunit/html/directives/actionButtonTemplate.html'
          *//*moduleName: '/staticfiles/adunit/html/directives/internalPlayerTemplate.html'*//*
      },*/

    // list of files to exclude
    exclude: [

    ],


    // test results reporter to use
    // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
    reporters: ['progress'],


    // web server port
    port: 9876,


    // enable / disable colors in the output (reporters and logs)
    colors: true,


    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,


    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,


    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera (has to be installed with `npm install karma-opera-launcher`)
    // - Safari (only Mac; has to be installed with `npm install karma-safari-launcher`)
    // - PhantomJS
    // - IE (only Windows; has to be installed with `npm install karma-ie-launcher`)
    browsers: ['Chrome'],


    // If browser does not capture in given timeout [ms], kill it
    captureTimeout: 60000,


    // Continuous Integration mode
    // if true, it capture browsers, run tests and exit
    singleRun: false
  });
};

我不断收到以下错误:

Failed to instantiate module /staticfiles/adunit/html/directives/actionButtonTemplate.html due to:
Error: [$injector:nomod]

任何帮助将不胜感激!

编辑:@MK Safi 的回答解决了我的问题.我错过了以下内容:

EDIT: @MK Safi's answer solved my problem. I was missing the following:

 ngHtml2JsPreprocessor: {
     'moduleName': 'Templates',

     // Function that transforms the path to look exactly like
     // you have it in templateUrl in your Angular code
     //
     // Mine looks like this
     cacheIdFromPath: function(filepath) {
         return filepath.match(//staticfiles/adunit/html/directives/.*.html/);
     }
  },

在每次测试之前:

 beforeEach(module('Templates'));

正则表达式指向与指令的templateUrl"相同的路径很重要,因为 html2js 将使用此路径缓存这些模板(请参阅 html2js 了解更多详情)

it is important for the regular expression to point to the same path as the directive's "templateUrl", since html2js will cache those templates using this path (see html2js for more details about that)

推荐答案

我在测试中正确设置了此设置,并且您的设置看起来正确,除了一些事情.

I have this setup correctly in my tests and your setup looks right, except for a few things.

对您的 Karma 配置文件进行以下更改:

Make the following changes to your Karma config file:

ngHtml2JsPreprocessor = {
  'moduleName': 'Templates',

  // Function that transforms the path to look exactly like 
  // you have it in templateUrl in your Angular code
  //
  // Mine looks like this
  cacheIdFromPath: function(filepath) {
    return filepath.match(/views/.*/)[0]
  }
}

然后在您的测试的 beforeEach 中包含您在上面的 Karma 配置中指定的 Templates 模块:module('Templates')

Then in your test's beforeEach include the Templates module that you specified in your Karma config above: module('Templates')

beforeEach(function() {
  module('Templates')
})

相关文章