Ich definiere einen Setup-Code in der Funktion config
eines Angular module
, den ich testen will. Es ist mir unklar, wie ich das machen soll. Unten ist ein vereinfachter Testfall, der zeigt, wie ich feststecke:
Das ist eindeutig nicht der richtige Weg, weil ich den folgenden Fehler bekomme:
%Vor%Ein vollständiges, lauffertiges Angular-Projekt mit dem oben genannten Testcode finden Sie auf GitHub . Wenn Sie wissen, was mit diesem Szenario zu tun ist, antworten Sie bitte hier auf Stack Overflow. Bonuspunkte, wenn Sie auch eine Pull-Anfrage an das GitHub Repo senden.
Verwenden Sie run
anstelle von config
, wenn Ihre Initialisierung das Eingeben von Diensten erfordert. Die Funktion config
kann nur Anbieter und Konstanten als Parameter empfangen, nicht instanziierte Dienste wie $http
( relevante Dokumente) ).
Initialisieren Sie Ihr Modul zum Testen
%Vor%So sieht die Vollversion aus wie
%Vor%Hier ist auch ein Beispiel zum Testen des Config-Blocks, um zu überprüfen, ob eine Methode auf einem Provider aufgerufen wurde: Ссылка
mzulch ist richtig , um darauf hinzuweisen, dass Dienste nicht in einen angular.module(...).config
-Block injiziert werden können. Er bietet auch die richtige Lösung für das Szenario, in dem Sie tatsächlich Dienste im Modulinitialisierungscode verwenden müssen: Verwenden Sie den Block .run
anstelle des Blocks .config
. Seine Antwort funktioniert perfekt für dieses Szenario.
Die Frage, wie ein Komponententest für den .config
-Block geschrieben wird, bleibt bestehen. Lassen Sie uns den naieve-Code von meiner Frage in ein Szenario anpassen, in dem .config
eigentlich gerechtfertigt ist. Das folgende Snippet fügt eine Anbieterabhängigkeit anstelle einer Dienstabhängigkeit ein:
Diesmal ist die Implementierung von 'myModule'
korrekt. Der Komponententest jedoch, der dem Versuch in meiner Frage analog ist, ist immer noch falsch. Jetzt gibt mir Karma den folgenden Fehler:
Dieser kryptische Fehler stammt von der inject
, die als zweites Argument an die it
übergeben wird. Beachten Sie, dass Provider
stottert. Dies liegt daran, dass inject
nach dem Anbieter für $httpProvider
sucht. Ein "Meta-Anbieter", wie wir es nennen können. Solche Dinge gibt es im Angular-Framework nicht, aber inject
versucht es trotzdem, weil erwartet, dass Sie nur nach Service-Abhängigkeiten fragen . Dienste haben Provider, zum Beispiel $http
hat $httpProvider
.
So inject
(vollständiger Name: angular.mock.inject
, hier global verfügbar) ist nicht der richtige Weg, um $httpProvider
im Testfall zu erhalten. Der richtige Weg ist die Definition einer anonymen Modulkonfigurationsfunktion mit module
( angular.mock.module
), die über eine Variable schließt, in der wir den Provider erfassen können. Dies funktioniert, weil Provider zur Konfigurationszeit injiziert werden können (siehe Link am Ende von mzulchs Antwort sowie meinem eigenen Anfrage zu meiner anderen Frage nach Details zu Konfigurationszeit und Laufzeit). Es sieht so aus:
Ein weiterer Fehler in meinem naieve-Testfall ist, dass ich versuche, 'myModule'
s Konfigurationsschritte auszuführen, indem ich angular.module('myModule')
aufruft. Zu Testzwecken sollte ich stattdessen das globale module
( angular.mock.module
) verwenden, und der weiseste Ort hierfür ist das beforeEach
Fixture. Abschließend macht der folgende Code die Aufgabe:
Ich habe mich dafür entschieden, das inject()
am Anfang meines Testfalls zu setzen, aber ich könnte es auch am Ende von beforeEach
setzen. Der Vorteil des letzteren Ansatzes wäre, dass ich den Aufruf von inject
an einer Stelle schreiben kann und nicht in jedem Testfall wiederholen muss. Der Vorteil des hier gewählten Ansatzes besteht darin, dass in späteren beforeEach
es oder sogar mehr Module zum Injektor hinzugefügt werden können in einzelnen Testfällen.
Ich habe diese alternative Lösung zu einem neuen Zweig auf GitHub verschoben .
Tags und Links javascript angularjs angular-mock karma-jasmine karma-runner