J’écris des tests de directive pour AngularJS avec Jasmine et utilise templateUrl avec eux: https://gist.github.com/tanepiper/62bd10125e8408def5cc
Cependant, lorsque je lance le test, l’erreur est incluse dans le fichier:
Error: Unexpected request: GET views/currency-select.html
D’après ce que j’ai lu dans les documents, je pensais que je le faisais correctement, mais cela ne semble pas être le cas – qu’est-ce que je manque ici?
Merci
Toutes les requêtes HTTP sont traitées localement à l’aide de règles que vous spécifiez et aucune n’est transmise au serveur. Les modèles étant demandés via HTTP, ils sont également traités localement. Comme vous n’avez rien spécifié lorsque votre application tente de se connecter à views/currency-select.html
, elle vous indique qu’elle ne sait pas comment la gérer. Vous pouvez facilement indiquer à ngMockE2E de transmettre votre requête de modèle:
$httpBackend.whenGET('views/currency-select.html').passThrough();
N’oubliez pas que vous pouvez également utiliser des expressions régulières dans vos chemins de routage pour passer par tous les modèles, si vous le souhaitez.
Les documents en discutent plus en détail: http://docs.angularjs.org/api/ngMockE2E.$httpBackend
Vous devrez utiliser l’ $injector
pour accéder au nouveau backend. À partir des documents liés:
var $httpBackend; beforeEach(inject(function($injector) { $httpBackend = $injector.get('$httpBackend'); $httpBackend.whenGET('views/currency-select.html').respond(200, ''); }));
La méthode Karma consiste à charger le modèle HTML dynamicment dans $ templateCache. vous pouvez simplement utiliser le pré-processeur html2js karma, comme expliqué ici
cela revient à append des templates ‘ .html’ à vos fichiers dans le fichier conf.js ainsi que des préprocesseurs = {‘ .html’: ‘html2js’};
et utilise
beforeEach(module('..')); beforeEach(module('...html', '...html'));
dans votre fichier de test js
S’il s’agit d’un test unitaire, vous n’aurez pas access à $httpBackend.passthrough()
. Ce n’est disponible que dans ngMock2E2, pour les tests de bout en bout. Je suis d’accord avec les réponses concernant ng-html2js
(autrefois appelé html2js), mais j’aimerais les développer pour fournir une solution complète ici.
Pour rendre votre directive, Angular utilise $http.get()
pour récupérer votre modèle depuis templateUrl
. Comme il s’agit de tests unitaires et que les $http.get()
angular-mocks
sont chargés, angular-mocks
intercepte l’appel à $http.get()
et vous donne la Unexpected request: GET
erreur Unexpected request: GET
. Vous pouvez essayer de trouver des moyens de contourner cela, mais il est beaucoup plus simple d’utiliser simplement $templateCache
angular pour précharger vos modèles. De cette façon, $http.get()
ne sera même pas un problème.
C’est ce que le préprocesseur ng-html2js fait pour vous. Pour le faire fonctionner, installez-le d’abord:
$ npm install karma-ng-html2js-preprocessor --save-dev
Ensuite, configurez-le en ajoutant / mettant à jour les champs suivants dans votre karma.conf.js
{ files: [ // // all your other files // //your htmp templates, assuming they're all under the templates dir 'templates/**/*.html' ], preprocessors: { // // your other preprocessors // // // tell karma to use the ng-html2js preprocessor "templates/**/*.html": "ng-html2js" }, ngHtml2JsPreprocessor: { // // Make up a module name to contain your templates. // We will use this name in the jasminee test code. // For advanced configs, see https://github.com/karma-runner/karma-ng-html2js-preprocessor moduleName: 'test-templates', } }
Enfin, dans votre code de test, utilisez le module test-templates
que vous venez de créer. Ajoutez simplement test-templates
de test-templates
à l’appel de module que vous effectuez généralement dans beforeEach
, comme ceci:
beforeEach(module('myapp', 'test-templates'));
Il devrait être facile de naviguer à partir de maintenant. Pour un examen plus approfondi de ce scénario et d’autres scénarios de test directifs, consultez ce post.
Vous pourriez peut-être obtenir le $templatecache
de l’injecteur et faire quelque chose comme
$templateCache.put("views/currency-select.html","");
où à la place de
vous metsortingez votre modèle.
Après cela, vous configurez votre directive et cela devrait fonctionner très bien!
Si cela ne fonctionne toujours pas, utilisez fiddler pour voir le contenu du fichier js généré dynamicment par le processeur htmltojs et vérifiez le chemin du fichier modèle.
Ce devrait être quelque chose comme ça
angular.module('app/templates/yourtemplate.html', []).run(function($templateCache) { $templateCache.put('app/templates/yourtemplate.html',
Dans mon cas, ce n’était pas la même chose que dans ma directive actuelle qui causait le problème.
Avoir le templateURL exactement le même dans tous les endroits m’a permis de passer au travers.
Comme demandé, convertir un commentaire en réponse.
Pour les personnes qui souhaitent utiliser la réponse de @ Lior dans les applications Yeoman :
Parfois, la manière dont les modèles sont référencés dans karma config et, par conséquent, les noms des modules produits par ng-html2js
ne correspondent pas aux valeurs spécifiées comme templateUrl
dans les définitions de directives.
Vous aurez besoin d’ajuster les noms de module générés pour correspondre à templateUrl
s.
Celles-ci pourraient être utiles:
c’est par exemple comment tester la directive qui utilise partial comme templateUrl
describe('with directive', function(){ var scope, comstack, element; beforeEach(module('myApp'));//myApp module beforeEach(inject(function($rootScope, $comstack, $templateCache){ scope = $rootScope.$new(); comstack = $comstack; $templateCache.put('view/url.html', '- {{ foo }}
' + '- {{ bar }}
' + '- {{ baz }}
' + '
'); scope.template = { url: 'view/url.html' }; scope.foo = 'foo'; scope.bar = 'bar'; scope.baz = 'baz'; scope.$digest(); element = comstack(angular.element( '' + '' + '' + ' ' ))(scope); scope.$digest(); })); it('should copy scope parameters to ngInclude partial', function(){ var isolateScope = element.find('div').eq(0).scope(); expect(isolateScope.foo).toBeDefined(); expect(isolateScope.bar).toBeDefined(); expect(isolateScope.baz).toBeDefined(); }) });
Si vous utilisez le plugin jasminee- maven avec RequireJS, vous pouvez utiliser le plug-in de texte pour charger le contenu du modèle dans une variable, puis le placer dans le cache du modèle.
define(['angular', 'text!path/to/template.html', 'angular-route', 'angular-mocks'], function(ng, directiveTemplate) { "use ssortingct"; describe('Directive TestSuite', function () { beforeEach(inject(function( $templateCache) { $templateCache.put("path/to/template.html", directiveTemplate); })); }); });