Ich schreibe Direktiventests für AngularJS mit Jasmine und verwende dabei templateUrl: https://Gist.github.com/tanepiper/62bd10125e8408def5cc
Wenn ich jedoch den Test durchführe, wird der Fehler im Gist angezeigt:
Error: Unexpected request: GET views/currency-select.html
Nach dem, was ich in den Dokumenten gelesen habe, dachte ich, ich mache das richtig, aber es scheint nicht so - was fehle ich hier?
Vielen Dank
Alle HTTP-Anforderungen werden lokal nach von Ihnen festgelegten Regeln verarbeitet, und es werden keine übergeben zum Server. Da Vorlagen über HTTP angefordert werden, werden auch diese lokal verarbeitet. Da Sie bei dem Versuch, eine Verbindung zu views/currency-select.html
Herzustellen, nichts angegeben haben, wird Ihnen mitgeteilt, dass Sie nicht wissen, wie Sie damit umgehen sollen. Sie können ngMockE2E ganz einfach anweisen, Ihre Vorlagenanfrage weiterzuleiten:
$httpBackend.whenGET('views/currency-select.html').passThrough();
Denken Sie daran, dass Sie auch reguläre Ausdrücke in Ihren Routing-Pfaden verwenden können, um alle Vorlagen zu durchlaufen, wenn Sie möchten.
In den Dokumenten wird dies genauer erläutert: http://docs.angularjs.org/api/ngMockE2E.$httpBackend
Sie müssen den $injector
Benutzen, um auf das neue Backend zuzugreifen. Aus den verlinkten Dokumenten:
var $httpBackend;
beforeEach(inject(function($injector) {
$httpBackend = $injector.get('$httpBackend');
$httpBackend.whenGET('views/currency-select.html').respond(200, '');
}));
die Karma-Methode besteht darin, die HTML-Vorlage dynamisch in $ templateCache zu laden. Sie könnten einfach den html2js-Karma-Pre-Prozessor verwenden, wie erklärt hier
dies läuft darauf hinaus, Vorlagen '. html' zu Ihren Dateien in der Datei conf.js sowie Präprozessoren = {'. html': 'html2js' hinzuzufügen. };
und verwenden
beforeEach(module('..'));
beforeEach(module('...html', '...html'));
in deine js testing datei
Wenn dies ein Unit-Test ist, haben Sie keinen Zugriff auf $httpBackend.passthrough()
. Dies ist nur in ngMock2E2 für End-to-End-Tests verfügbar. Ich stimme den Antworten mit ng-html2js
(Früher als html2js bezeichnet) zu, möchte sie aber gerne erweitern, um hier eine vollständige Lösung bereitzustellen.
Zum Rendern Ihrer Direktive verwendet Angular $http.get()
, um Ihre Vorlage aus templateUrl
abzurufen. Dies ist ein Unit-Test, und angular-mocks
Wird geladen , angular-mocks
Fängt den Aufruf von $http.get()
ab und gibt den Fehler Unexpected request: GET
Aus. Sie können versuchen, Wege zu finden, um dies zu umgehen, aber es ist viel einfacher, nur winklige $templateCache
, Um Ihre Vorlagen vorab zu laden. Auf diese Weise wird $http.get()
nicht einmal ein Problem sein.
Das ist, was der Präprozessor ng-html2js für Sie tut. Um es zum Laufen zu bringen, installieren Sie es zuerst:
$ npm install karma-ng-html2js-preprocessor --save-dev
Dann konfigurieren Sie es durch Hinzufügen/Aktualisieren der folgenden Felder in Ihrem 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 jasmine test code.
// For advanced configs, see https://github.com/karma-runner/karma-ng-html2js-preprocessor
moduleName: 'test-templates',
}
}
Verwenden Sie schließlich in Ihrem Testcode das soeben erstellte Modul test-templates
. Fügen Sie einfach test-templates
Zu dem Modulaufruf hinzu, den Sie normalerweise in beforeEach
ausführen:
beforeEach(module('myapp', 'test-templates'));
Von hier aus sollte es ruhig laufen. Weitere Informationen zu diesem und anderen Direktiventestszenarien finden Sie in diesem Beitrag
Sie könnten vielleicht den $templatecache
Vom Injektor abrufen und dann so etwas tun
$templateCache.put("views/currency-select.html","<div.....>");
wo würden Sie anstelle von <div.....>
Ihre Vorlage einfügen?.
Danach richten Sie Ihre Direktive ein und es sollte gut funktionieren!
Wie gewünscht, einen Kommentar in eine Antwort umwandeln.
Für die Leute, die die Antwort von @ Lior in Yeoman Apps nutzen möchten:
Manchmal wird in der Karma-Konfiguration auf die Art und Weise verwiesen, wie auf die Vorlagen verwiesen wird, und folglich auf die Namen der Module, die von ng-html2js
stimmen nicht mit den Werten überein, die in den Richtliniendefinitionen als templateUrl
s angegeben sind.
Sie müssen die generierten Modulnamen so anpassen, dass sie mit templateUrl
s übereinstimmen.
Diese könnten hilfreich sein:
Wenn dies immer noch nicht funktioniert, verwenden Sie fiddler, um den Inhalt der von htmltojs processor dynamisch generierten js-Datei anzuzeigen und den Pfad der Vorlagendatei zu überprüfen.
Es sollte so etwas sein
angular.module('app/templates/yourtemplate.html', []).run(function($templateCache) {
$templateCache.put('app/templates/yourtemplate.html',
In meinem Fall war es nicht dasselbe wie in meiner eigentlichen Richtlinie, was das Problem verursachte.
Die templateURL an allen Stellen exakt gleich zu haben, hat mich durchgebracht.
dies ist ein Beispiel zum Testen einer Direktive, die partial als templateUrl verwendet
describe('with directive', function(){
var scope,
compile,
element;
beforeEach(module('myApp'));//myApp module
beforeEach(inject(function($rootScope, $compile, $templateCache){
scope = $rootScope.$new();
compile = $compile;
$templateCache.put('view/url.html',
'<ul><li>{{ foo }}</li>' +
'<li>{{ bar }}</li>' +
'<li>{{ baz }}</li>' +
'</ul>');
scope.template = {
url: 'view/url.html'
};
scope.foo = 'foo';
scope.bar = 'bar';
scope.baz = 'baz';
scope.$digest();
element = compile(angular.element(
'<section>' +
'<div ng-include="template.url" with="{foo : foo, bar : bar, baz : baz}"></div>' +
'<div ng-include="template.url" with=""></div>' +
'</section>'
))(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();
})
});
Wenn Sie das jasmine-maven-plugin zusammen mit RequireJS verwenden, können Sie das text plugin verwenden, um den Vorlageninhalt in eine Variable zu laden und ihn dann in den Vorlagencache zu legen.
define(['angular', 'text!path/to/template.html', 'angular-route', 'angular-mocks'], function(ng, directiveTemplate) {
"use strict";
describe('Directive TestSuite', function () {
beforeEach(inject(function( $templateCache) {
$templateCache.put("path/to/template.html", directiveTemplate);
}));
});
});