web-dev-qa-db-fra.com

Karma 'Demande inattendue' lors du test de la directive angulaire, même avec ng-html2js

Après avoir passé la dernière journée à essayer de faire en sorte que cela fonctionne, j'ai constaté que je revenais à la même erreur que celle que j'avais au début:

Erreur: demande inattendue: GET test-directive.html

J'utilise Karma et Jasmine pour tester les directives en angulaire. J'ai parcouru des questions similaires sur StackOverflow, mais je constate que tout ce qui a été essayé dans les autres exemples est inutile. 

Structure du code

Test-App
- src
--tonnelle
- lib
- js
--modules
--- testDir
---- test.js
---- test-directive.html
----tester
----- test.spec.js
-tester
- 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.
        });
    });
});

Nous avons raccourci quelques dossiers pour nous en tenir au problème. En appelant beforeEach(module('dir-templates')), il devrait charger tous les fichiers .html correspondants dans le $ templateCache et empêcher la requête GET de générer l'erreur. 

Toute aide serait appréciée car elle me rend vraiment dingue. Veuillez commenter si vous avez des questions supplémentaires.

25
dmaloney.calu

Donc, un mal de tête laborieux pour ce qui semble être une solution à deux lignes. Après avoir ouvert Karma dans Chrome (au lieu de PhantomJS) et examiné les fichiers source, j'ai remarqué que lorsque ng-html2js attache la directive à $ templateCache, il utilise le chemin complet, pas celui fourni dans la définition de la directive.

En bref, 'src/modules/test/test-directive.html.js' !== 'test-directive.html.js'.

Pour ce faire, modifiez le fichier ngHtml2JsProcessor de karma.conf.js comme suit:

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

Et le templateUrl de la déclaration de directive ressemble à ceci:

templateUrl: 'modules/test/test-directive.html'
29
dmaloney.calu

Pour ajouter aux commentaires sur le fait de s'assurer que le nom du modèle correspondant correspond au préfixe (sans barre oblique, etc.), il faut également vérifier la casse.

La clé de cache du modèle est sensible à la casse. Par conséquent, assurez-vous que vos directives référencent les fichiers HTML à l'aide de la casse appropriée. Les clés de cache de modèle générées par ngHtml2JsPreprocessor utilisent la casse du nom de fichier réel et des noms de répertoire sur le système de fichiers. 

Donc, si votre fichier s'appelle Test-Directive.html ou votre dossier s'appelle "Modules" mais que votre directive fait référence à "modules/test-directive.html", elle ne sera pas résolue à partir du cache.

La sensibilité à la casse n'est pas un problème avec l'utilisation réelle (sans test) du templateurl de votre directive (la requête GET est évidemment insensible à la casse et la clé de cache du modèle sera générée sur la base de la requête GET initiale, c'est-à-dire ce qui a été spécifié dans votre directive). 

0
user2842949

Quelques conseils de débogage lors de la réception de cette erreur: 

Lorsque Karma Chrome Launcher ouvre le navigateur, recherchez le modèle à l'origine de l'erreur. Dans mon cas, il s'agissait de student-survey.html, vous verrez apparaître un student-survey.html.js, le modèle placé dans un cache de modèle angulaire. En inspectant ce fichier html.js, vous verrez un identifiant de cache: $templateCache.put('/app/views/student-survey.html',....

Vous devez vous assurer que l'ID de cache, dans ce cas app/views/student-survey.html correspond à ce qui est référencé dans votre application, dans mon cas, il manquait un "/" final que j'ai réussi à corriger en plaçant un / dans la section prependPrefix du ngHtml2JsPreprocessor section dans mon karma.conf.js:

ngHtml2JsPreprocessor: { prependPrefix: '/', moduleName: 'templates' }

0
Mohammad Sepahvand