Ich habe eine AngularJS-Direktive, die eine templateUrl
definierte hat. Ich versuche es mit Jasmine zu testen.
Mein Jasmine JavaScript sieht wie folgt aus , gemäß der Empfehlung von dieser :
describe('module: my.module', function () {
beforeEach(module('my.module'));
describe('my-directive directive', function () {
var scope, $compile;
beforeEach(inject(function (_$rootScope_, _$compile_, $injector) {
scope = _$rootScope_;
$compile = _$compile_;
$httpBackend = $injector.get('$httpBackend');
$httpBackend.whenGET('path/to/template.html').passThrough();
}));
describe('test', function () {
var element;
beforeEach(function () {
element = $compile(
'<my-directive></my-directive>')(scope);
angular.element(document.body).append(element);
});
afterEach(function () {
element.remove();
});
it('test', function () {
expect(element.html()).toBe('asdf');
});
});
});
});
Wenn ich dies in meinem Jasmine-Spezifikationsfehler ausführe, wird der folgende Fehler angezeigt:
TypeError: Object #<Object> has no method 'passThrough'
Ich möchte nur, dass die templateUrl so geladen wird, wie sie ist - ich möchte sie nicht verwenden respond
. Ich glaube, dies hängt möglicherweise damit zusammen, dass ngMock anstelle von ngMockE2E verwendet wird . Wenn dies der Schuldige ist, wie verwende ich letzteres anstelle des ersteren?
Danke im Voraus!
.passThrough();
auf diese Weise verwendet, aber aus den Dokumenten haben Sie Folgendes versucht:$httpBackend.expectGET('path/to/template.html'); // do action here $httpBackend.flush();
Ich denke, dies passt besser zu Ihrer Verwendung - Sie möchten die Anfrage nicht abfangen, dhwhenGet()
stattdessen überprüfen, ob sie gesendet wurde, und dann tatsächlich schicken Sie es?expectGET
das Anfragen sendet ... zumindest sofort. In den Dokumenten hat ihr Beispiel mit/auth.py
ein$httpBackend.when
vor dem$httpBackend.expectGET
und$httpBackend.flush
ruft auf.expectGet
wird nur geprüft, ob eine Anfrage versucht wurde.$httpBackend
Mock zu sagen , dass er die in der Direktive unter angegebene URL tatsächlich verwendentemplateUrl
und sie abrufen soll. Ich dachte, ichpassThrough
würde das tun. Kennen Sie einen anderen Weg, dies zu tun?Antworten:
Sie haben Recht, dass es mit ngMock zusammenhängt. Das ngMock-Modul wird automatisch für jeden Angular-Test geladen und initialisiert den Mock
$httpBackend
, um jede Verwendung des$http
Dienstes zu handhaben , einschließlich des Abrufs von Vorlagen. Das Vorlagensystem versucht, die Vorlage durchzuladen,$http
und es wird eine "unerwartete Anforderung" an den Mock.Was Sie brauchen, um die Vorlagen vorab in das zu laden,
$templateCache
damit sie bereits verfügbar sind, wenn Angular sie anfordert, ohne sie zu verwenden$http
.Die bevorzugte Lösung: Karma
Wenn Sie Karma zum Ausführen Ihrer Tests verwenden (und dies sollten Sie auch tun ), können Sie es so konfigurieren, dass die Vorlagen mit dem Präprozessor ng-html2js für Sie geladen werden . Ng-html2js liest die von Ihnen angegebenen HTML-Dateien und konvertiert sie in ein Angular-Modul, das die vorinstalliert
$templateCache
.Schritt 1: Aktivieren und konfigurieren Sie den Präprozessor in Ihrem
karma.conf.js
Wenn Sie Yeoman als Gerüst für Ihre App verwenden, funktioniert diese Konfiguration
Schritt 2: Verwenden Sie das Modul in Ihren Tests
Ein vollständiges Beispiel finden Sie in diesem kanonischen Beispiel des Angular-Test-Gurus Vojta Jina . Es enthält ein komplettes Setup: Karma-Konfiguration, Vorlagen und Tests.
Eine Nicht-Karma-Lösung
Wenn Sie Karma aus irgendeinem Grund nicht verwenden (ich hatte einen unflexiblen Erstellungsprozess in der Legacy-App) und nur in einem Browser testen, habe ich festgestellt, dass Sie die Übernahme von ngMock umgehen können, indem Sie
$httpBackend
die Vorlage mithilfe eines rohen XHR abrufen und legen Sie es in die$templateCache
. Diese Lösung ist viel weniger flexibel, erledigt aber die Aufgabe vorerst.Aber im Ernst. Benutze Karma . Das Einrichten erfordert ein wenig Arbeit, aber Sie können alle Ihre Tests in mehreren Browsern gleichzeitig über die Befehlszeile ausführen. Sie können es also als Teil Ihres kontinuierlichen Integrationssystems verwenden und / oder es zu einer Tastenkombination in Ihrem Editor machen. Viel besser als Alt-Tab-Refresh-Ad-Infinitum.
quelle
preprocessors
Dateimuster (z. B."path/to/templates/**/*.html"
) zumfiles
Abschnitt in hinzuzufügenkarma.conf.js
.false
Parameter für denopen
Aufruf des XHR verwende , um ihn synchron zu machen. Wenn Sie dies nicht tun, wird die Ausführung fröhlich fortgesetzt und die Ausführung Ihrer Tests gestartet, ohne dass die Vorlage geladen wird. Damit haben Sie wieder das gleiche Problem: 1) Die Anforderung einer Vorlage geht aus. 2) Der Test wird ausgeführt. 3) Der Test kompiliert eine Direktive und die Vorlage wird noch nicht geladen. 4) Angular fordert die Vorlage über seinen$http
verspotteten Dienst an. 5) Der Mock-$http
Service beschwert sich: "unerwartete Anfrage".npm install --save-dev karma-ng-html2js-preprocessor
) installieren und eskarma.conf.js
gemäß stackoverflow.com/a/19077966/859631 zum Plugins-Bereich Ihres hinzufügen .Am Ende habe ich den Vorlagen-Cache abgerufen und die Ansicht dort abgelegt. Ich habe keine Kontrolle darüber, ob ich ngMock nicht benutze. Es stellt sich heraus:
quelle
Dieses anfängliche Problem kann gelöst werden, indem Folgendes hinzugefügt wird:
Dies liegt daran, dass standardmäßig versucht wird, $ httpBackend im ngMock- Modul zu finden, und dass es nicht voll ist.
quelle
Die Lösung, die ich erreicht habe, benötigt jasmine-jquery.js und einen Proxyserver.
Ich habe diese Schritte befolgt:
Fügen Sie jasmine-jquery.js zu Ihren Dateien hinzu
Fügen Sie einen Proxyserver hinzu, der Ihre Geräte verwaltet
In Ihrer Spezifikation
beschreiben ('MySpec', function () {var $ scope, template; jasmine.getFixtures (). fixturesPath = 'public / partials /'; // benutzerdefinierter Pfad, damit Sie die reale Vorlage bereitstellen können, die Sie in der App vor jeder Funktion verwenden () {template = angle.element ('');
});
Führen Sie einen Server im Stammverzeichnis Ihrer App aus
Python -m SimpleHTTPServer 3502
Führen Sie Karma.
Ich habe eine Weile gebraucht, um das herauszufinden, da ich viele Beiträge durchsuchen musste. Ich denke, die Dokumentation dazu sollte klarer sein, da es sich um ein so wichtiges Thema handelt.
quelle
localhost/base/specs
und beim Hinzufügen eines Proxyservers, auf dem das Problempython -m SimpleHTTPServer 3502
behoben wurde. Sie, mein Herr, sind ein Genie!Meine Lösung:
test/karma-utils.js
::karma.config.js
::der Test:
quelle
static
, z. B.beforeEach(preloadTemplate(static_url +'seed/partials/beChartDropdown.html'));
Danke!Wenn Sie Grunt verwenden, können Sie Grunt-Angular-Templates verwenden. Es lädt Ihre Vorlagen in den templateCache und ist unabhängig von Ihrer Spezifikationskonfiguration.
Meine Beispielkonfiguration:
quelle
Ich habe das gleiche Problem auf eine etwas andere Weise gelöst als die gewählte Lösung.
Zuerst habe ich das ng-html2js Plugin für Karma installiert und konfiguriert . In der Datei karma.conf.js:
Dann habe ich das in beforeEach erstellte Modul geladen. In Ihrer Spec.js-Datei:
Dann habe ich $ templateCache.get verwendet, um es in einer Variablen zu speichern. In Ihrer Spec.js-Datei:
Schließlich habe ich es so getestet. In Ihrer Spec.js-Datei:
quelle
Um die Vorlage HTML dynamisch in $ templateCache zu laden, können Sie einfach den Karma-Vorprozessor html2js 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
in Ihre js Testdatei
quelle
Uncaught SyntaxError: Unexpected token <
Wenn Sie Karma verwenden, sollten Sie karma-ng-html2js-preprocessor verwenden , um Ihre externen HTML-Vorlagen vorkompilieren zu können, und vermeiden, dass Angular versucht, sie während der Testausführung per HTTP abzurufen . Ich hatte einige Probleme damit - in meinem Fall wurden die Teilpfade von templateUrl während der normalen App-Ausführung, aber nicht während der Tests aufgelöst - aufgrund von Unterschieden in den Strukturen von App und Testverzeichnis.
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.
quelle
Wenn Sie in Ihren Tests requirejs verwenden, können Sie das 'text'-Plugin verwenden, um die HTML-Vorlage abzurufen und in den $ templateCache einzufügen.
quelle
Ich behebe dieses Problem beim Kompilieren aller Vorlagen in den Vorlagencache. Ich benutze Schluck, Sie können ähnliche Lösung auch für Grunzen finden. Meine templateUrls in Direktiven, Modalitäten sehen aus wie
Fügen Sie ein neues npm-Paket in meiner package.json hinzu
"gulp-angular-templatecache": "1.*"
Fügen Sie in der Gulp-Datei den Vorlagencache und eine neue Aufgabe hinzu:
var templateCache = require('gulp-angular-templatecache'); ... ... gulp.task('compileTemplates', function () { gulp.src([ './app/templates/**/*.html' ]).pipe(templateCache('templates.js', { transformUrl: function (url) { return '/templates/' + url; } })) .pipe(gulp.dest('wwwroot/assets/js')); });
Fügen Sie alle js-Dateien in index.html hinzu
<script src="/assets/js/lib.js"></script> <script src="/assets/js/app.js"></script> <script src="/assets/js/templates.js"></script>
Genießen!
quelle