Ich schreibe Direktiventests für AngularJS mit Jasmine und verwende templateUrl mit ihnen: https://gist.github.com/tanepiper/62bd10125e8408def5cc
Wenn ich den Test durchführe, wird jedoch der folgende Fehler 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 fehlt mir hier?
Vielen Dank
unit-testing
angularjs
jasmine
angularjs-directive
Tane Piper
quelle
quelle
Antworten:
Wenn Sie ngMockE2E oder ngMock verwenden:
Alle HTTP-Anforderungen werden lokal nach den von Ihnen angegebenen Regeln verarbeitet und keine werden an den Server übergeben. Da Vorlagen über HTTP angefordert werden, werden auch sie lokal verarbeitet. Da Sie beim Versuch, eine Verbindung zu Ihrer App herzustellen, nichts angegeben haben, wissen
views/currency-select.html
Sie nicht, wie Sie damit umgehen sollen. Sie können ngMockE2E leicht anweisen, Ihre Vorlagenanforderung weiterzuleiten:$httpBackend.whenGET('views/currency-select.html').passThrough();
Denken Sie daran, dass Sie in Ihren Routing-Pfaden auch reguläre Ausdrücke verwenden können, um alle Vorlagen zu durchlaufen, wenn Sie möchten.
In den Dokumenten wird dies ausführlicher erläutert: http://docs.angularjs.org/api/ngMockE2E.$httpBackend
Andernfalls verwenden Sie Folgendes:
Sie müssen das verwenden,
$injector
um auf das neue Backend zuzugreifen. Aus den verknüpften Dokumenten:var $httpBackend; beforeEach(inject(function($injector) { $httpBackend = $injector.get('$httpBackend'); $httpBackend.whenGET('views/currency-select.html').respond(200, ''); }));
quelle
ngMock
Modul, sondern auf dasngMockE2E
Modul, das das unterstütztpassThrough()
. Normalerweise wird es bei Komponententests nicht verwendet, da für Komponententests keine HTTP-Anforderungen wie Vorlagen erforderlich sein sollten. Falls dies jedoch der Fall ist und der Build sie nicht kompiliert, kann das E2E-Backend verwendet werden.Die Karma-Methode besteht darin, die HTML-Vorlage dynamisch in $ templateCache zu laden. Sie können einfach den html2js Karma-Vorprozessor verwenden, wie hier erläutert
Dies läuft darauf hinaus, Ihren Dateien in der Datei conf.js Vorlagen ' .html' sowie Präprozessoren hinzuzufügen = {' .html': 'html2js'};
und verwenden
beforeEach(module('..')); beforeEach(module('...html', '...html'));
in Ihre js Testdatei
quelle
Wenn dies ein Komponententest ist, haben Sie keinen Zugriff darauf
$httpBackend.passthrough()
. Dies ist nur in ngMock2E2 für End-to-End-Tests verfügbar. Ich bin mit den Antworten einverstandenng-html2js
(früher html2js genannt), möchte sie aber erweitern, um hier eine vollständige Lösung bereitzustellen.Zum Rendern Ihrer Direktive ruft Angular
$http.get()
Ihre Vorlage abtemplateUrl
. Da dies ein Unit-Test ist undangular-mocks
geladen wird, wirdangular-mocks
der Aufruf von abgefangen$http.get()
und Sie erhalten denUnexpected request: GET
Fehler. Sie können versuchen, Wege zu finden, um dies zu umgehen, aber es ist viel einfacher, nur Winkel zu verwenden$templateCache
, um Ihre Vorlagen vorzuladen. Auf diese Weise$http.get()
wird nicht einmal ein Problem sein.Das ist es, 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
Konfigurieren Sie es dann, indem Sie die folgenden Felder in Ihrem hinzufügen / aktualisieren
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
test-templates
Sie schließlich in Ihrem Testcode das Modul, das Sie gerade erstellt haben. Fügen Sietest-templates
dem Modulaufruf, den Sie normalerweise ausführenbeforeEach
, einfach Folgendes hinzu :beforeEach(module('myapp', 'test-templates'));
Von hier an sollte es glatt sein. Weitere Informationen zu diesem und anderen Testszenarien für Richtlinien finden Sie in diesem Beitrag
quelle
Sie könnten vielleicht das
$templatecache
vom Injektor bekommen und dann so etwas tun$templateCache.put("views/currency-select.html","<div.....>");
Wo anstelle von
<div.....>
Ihnen würde Ihre Vorlage platzieren.Danach richten Sie Ihre Direktive ein und es sollte gut funktionieren!
quelle
Wenn dies immer noch nicht funktioniert, verwenden Sie Fiddler, um den Inhalt der vom htmltojs-Prozessor 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 tatsächlichen Richtlinie, die das Problem verursachte.
Die TemplateURL an allen Orten genau gleich zu haben, hat mich durchgebracht.
quelle
Konvertieren Sie einen Kommentar wie gewünscht in eine Antwort.
Für die Leute, die die Antwort von @ Lior in Yeoman- Apps nutzen möchten :
Manchmal
ng-html2js
stimmen die Art und Weise, wie auf die Vorlagen in der Karma-Konfiguration verwiesen wird, und folglich - die Namen der von produzierten Module nicht mit dentemplateUrl
in Direktivendefinitionen als s angegebenen Werten überein .Sie müssen die generierten Modulnamen an
templateUrl
s anpassen .Diese könnten hilfreich sein:
quelle
Dies ist ein Beispiel für das Testen von Direktiven, die teilweise als templateUrl verwenden
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(); }) });
quelle
Wenn Sie das Jasmin-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 Vorlagen-Cache 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); })); }); });
quelle