Warum schlägt dieser Test für den angular-google-maps-Anbieter fehl?

9

Ich versuche ein Modul zu testen, das angular-google-maps verwendet. Es schlägt fehl, weil angular.mock.inject uiGmapGoogleMapApiProvider nicht finden kann:

%Vor%

Ich kann nicht herausfinden, was falsch läuft. Hier ist der reduzierte Testfall:

%Vor%

Das Ganze ist als ein lauffähiges Angular-Projekt von GitHub . Wenn Sie das Problem finden, antworten Sie bitte hier auf Stack Overflow. Bonuspunkte, wenn Sie auch eine Pull-Anfrage an das GitHub-Repository senden.

    
Julian 11.08.2016, 16:16
quelle

2 Antworten

1

Hier spielen zwei Fallstricke eine Rolle, von denen keine etwas mit eckigen Google Maps zu tun hat.

Der erste Fehler liegt in der Unterscheidung zwischen Diensten und Anbietern. Die Dokumentation gibt an, dass Dienste, Fabriken, Werte und Konstanten Sonderfälle von Anbietern sind. Für einen relativen Anfänger wie mich scheint dies darauf hinzudeuten, dass Anbieter und Dienste überall auf die gleiche Art und Weise injiziert werden können. Das Gegenteil ist jedoch der Fall: An jeder Stelle, an der Abhängigkeiten injiziert werden können, können Sie entweder Anbieter oder Dienste injizieren, aber nie beides.

Der Grund für diese Kluft liegt in der strikten Trennung zwischen Konfigurationszeit und Laufzeit (siehe Moduldokumentation ). Anbieter sind während der Konfigurationszeit verfügbar, während Dienste während der Laufzeit verfügbar sind. Die Laufzeit beginnt nach dem Ende der Konfigurationszeit. Die Blöcke .config und .provider werden zur Konfigurationszeit ausgeführt, während die meisten anderen Blocktypen zur Laufzeit ausgeführt werden. Die Beziehung zwischen Provider- und Service-Definitionen wird im folgenden Codeschnipsel veranschaulicht, der aus der Provider-Dokumentation stammt:

%Vor%

Wie Sie sehen, ist ein Service innerhalb eines Providers definiert. Der Provider wird zur Konfigurationszeit definiert (äußerer Block, function MyServiceProvider ) und kann von anderen Anbietern abhängen. Der Dienst kann vom Anbieter mit der Methode .$get des Providers zur Laufzeit extrahiert werden, wie im inneren Block ( function MyService ) definiert, und kann von anderen Diensten abhängen. Ein Provider kann keine injizierte Abhängigkeit eines Services sein oder umgekehrt, aber Sie können eine Servicedefinition innerhalb einer Providerdefinition wie oben beschrieben verschachteln, um sie von Providern indirekt abhängig zu machen. Wenn Sie einen "Standalone" -Dienst mit einem angular.module(...).service -Block definieren, macht Angular etwas wie den obigen Code hinter Ihrem Rücken.

Der andere Nachteil ist, dass angular.mock.inject , das ist die inject aus dem Unit-Test in meiner Frage, kann nur Laufzeit-Injektionen tun. Für Konfigurationszeitinjektionen müssen Sie "die wirkliche Sache" machen, d. H. Nicht verspottete Injektion, indem Sie ein neues Modul mit Konfigurationszeitabhängigkeiten erstellen. Das ist was mguimard angedeutet hat. André Eife hat ein kurzes Tutorial veröffentlicht, in dem es darum geht, was zu tun ist Ich fand durch einen Link am Ende einer Antwort zu meiner anderen Frage.

Zusammenfassend ist hier der Code, der das Problem in meiner Frage beheben würde:

%Vor%

Das 'testAssist' Modul im Fixture ( beforeEach ) existiert nur zu dem Zweck, eine Konfigurationszeitabhängigkeit von uiGmapGoogleMapApiProvider zu haben, also kann ich letztere in der lokalen Variable gmapProvider erfassen. Die nachfolgenden Aufrufe von module und inject sind Buchhaltungstricks, um sicherzustellen, dass der config -Block von 'testAssist' ausgeführt wird. Dank des Captures muss innerhalb des Testfalls keine Injektion durchgeführt werden ( it ) und ich kann nur überprüfen, ob der Provider eine configure -Methode hat. Beachten Sie, dass der erste angular.module -Aufruf eine reguläre Moduldefinition ist, während der zweite module -Aufruf ein spezielles Konstrukt aus dem Mocking-Framework ( angular.mock ) ist.

Ich habe die obige Lösung auf den Zweig fix1 auf GitHub.

    
Julian 17.08.2016, 22:20
quelle
-1

Sie können keine Providerinstanz erhalten, indem Sie inject verwenden, stattdessen module verwenden

    
mguimard 11.08.2016 16:23
quelle