Question

After spending the last day trying to make this work, I've found that I've circled back around to the same error I was having at the beginning:

Error: Unexpected request: GET test-directive.html

I'm using Karma and Jasmine to test directives in Angular. I've looked through similar questions on StackOverflow, but find that everything that has been tried in the other examples is to no avail.

Code structure

Test-App
-src
--bower
--lib
--js
--modules
---testDir
----test.js
----test-directive.html
----test
-----test.spec.js
-test
--config
---karma.conf.js
--e2e

Karma Config

'use strict';
module.exports = function(config){
    config.set({
    basePath: '../../',
    frameworks: ['jasmine'],
    files: [
        // Angular
        'src/bower/angular/angular.js',
        // Mocks
        'src/bower/angular-mocks/angular-mocks.js',
        // Libraries
        'src/lib/**/*.js',
        // App
        'src/js/*.js',
        'src/modules/*/*.js',
        // Tests
        'src/modules/**/test/*spec.js',
        // Templates
        'src/modules/**/*.html'
    ],
    autoWatch: false,
    singleRun: true,
    reporters: ['progress'],
    browsers: ['PhantomJS'],

    preprocessors: {
        'src/modules/**/*.html': 'ng-html2js'
    },
    ngHtml2JsPreprocessor: {
        moduleName: 'dir-templates'
    },
    plugins: [
        'karma-jasmine',
        'karma-ng-html2js-preprocessor',
        'karma-phantomjs-launcher',
        'karma-chrome-launcher',
        'karma-junit-reporter'
    ]
    });
};

test.js

'use strict';
angular.module('modules.test', []).
directive('testDirective', [function() {
    return {
        restrict: 'E',
        templateUrl: 'test-directive.html',
        link: function($scope, $elem, $attrs) {
            $scope.someFn = function() {
                angular.noop();
            };
        }
    };
}]);

test-direct.html

<span>Hello World</span>

test.spec.js

'use strict';
describe('test module', function() {
    beforeEach(module('modules.test'));
    /* -- DIRECTIVES------------------ */
    describe('directives', function() {
        var $compile, $scope, elm;
        beforeEach(module('dir-templates');
        beforeEach(inject(function($compile, $rootScope) {
            $scope = $rootScope.$new();
            elm = angular.element('<test-directive></test-directive>');
            $compile(elm)($scope);
            $scope.$digest();
        }));
        it('should have one span tag', function(){
            //Jasmine test here to check for one span tag.
        });
    });
});

Have shortened a couple of files to stick to just where the issue is. In calling beforeEach(module('dir-templates')), it should be loading all of the matched .html files into the $templateCache and preventing the GET request that is throwing the error.

Any help would be appreciated as it's really been driving me nuts. Please comment if you have any additional questions.

Was it helpful?

Solution

So, a painstaking headache for what seems to be a two line fix. After opening Karma in Chrome (instead of PhantomJS) and looking at the source files, I noticed that when ng-html2js attaches the directive to the $templateCache it uses the entire path, not the one provided in the directive definition.

In short, 'src/modules/test/test-directive.html.js' !== 'test-directive.html.js'.

To achieve this, modify the karma.conf.js file ngHtml2JsProcessor to read like:

ngHtml2JsPreprocessor: {
    stripPrefix: 'src/',
    moduleName: 'dir-templates'
},

And the directive declaration's templateUrl to look like:

templateUrl: 'modules/test/test-directive.html'

OTHER TIPS

To add to the comments about making sure the template name being matched on matches the prefix (has no leading slash, etc.), one other thing to check for is case.

The template cache key is case sensitive, so make sure that your directives are referencing the html files using proper casing. The template cache keys that the ngHtml2JsPreprocessor generates use the casing of the actual file name and directory names on the file system.

So if your file is named Test-Directive.html or your folder is named "Modules" but your directive is referencing "modules/test-directive.html", it won't resolve from the cache.

Case sensitivity isn't an issue with real (non-test) usage of your directive's templateurl (the GET request obviously is case insensitive and the template cache key will be generated based on whatever the initial GET request was, ie. whatever was specified in your directive).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top