I am testing a custom AngularJS directive using Karma + Jasmine and the ngHtml2JsPreprocessor plugin to serve my directive template, but I donβt understand why my directive seems to be unable to access the template (the compiled element is empty). I defined templateUrl in the directive as follows:
templateUrl: 'templates/angular/mywidget.html'
my Karma configuration is as follows (its corresponding part):
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' ],
and in my test:
beforeEach(module('templates')); beforeEach(module('ngResource')); beforeEach(module('mywidget'));
The "fun" part is that if I test the template cache, the templates are downloaded and compiled:
beforeEach(inject(function(_$templateCache_) { var template = _$templateCache_.get('templates/angular/mywidget.html'); }));
there is a pattern! Why can't my directive use it? (it works fine in the browser). If I replace templateUrl with inline template in my directive, it will be displayed correctly in the test ... but I have to use an external template, it is unacceptable to insert it into a string ... I'm stuck !! Any smart idea?
UPDATE (what I have tried so far):
writing a new directive without logic (to exclude that the problem was in the implementation) is simple:
angular.module('modulename', []). directive('foo', function() { return { templateUrl: 'path/to/template.html' } });
simplify the contents of the template to:
<div>hello world</div>
change the path to the template
change template name
change the location of the karma configuration file
removes additional dependencies such as "ngResource" and similar
reinstalling all the dependencies of the bars (and clearing the cache)
reinstall all npm packages
run tests from the command line (I ran the test in Intellij Idea using the Karma plugin)
Tipping your fists on the table, throwing sequences of Fibonacci blasphemy that would kill dad if he listened to him!
(the latter, as a rule, leads me to a solution ... but not this time)
UPDATE 2:
I got around the problem by defining my directive like this:
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; });
Using this trick, my directive gets visualization properly in tests. This moment sounds like an error in AngularJS ... it cannot somehow load the template from the cache. I am extremely disappointed: (