2015-08-29 9 views
11

Also habe ich versucht, dies über Dokumentation selbst herauszufinden, aber ich komme nirgendwohin.Guice, DI, und Komponententests in Play 2.4

Ich habe einige einfache DI-Bindungen in einer Serviceklasse eingerichtet, die ein Repository-Objekt erstellt. Einfach. Wenn ich dies jedoch im Testmodus ausführe, führt @Inject nichts aus, und das Repository-Objekt wird niemals instanziiert.

@Inject 
TagRepository tagRepository; 

So auf der Linie, wo sie Verwendung im Testmodus ist, erhalten wir natürlich eine Nullpointer

tagRepository.tagExistsByName(tag); 

Diese sprudelt in meinem Test in etwa so:

[error] Test services.TagsServiceTest.testAddNewTag failed: java.lang.NullPointerException: null, took 0.097 sec 
[error]  at services.TagService.tagExists(TagService.java:27) 
[error]  at services.TagService.addNewTag(TagService.java:18) 
[error]  at services.TagsServiceTest.testAddNewTag(TagsServiceTest.java:29) 

Meine Frage Wie konfiguriere ich meine Anwendung, um Guice-Injektoren im Testmodus zu verwenden? Ich hatte dieses Problem mit meinen Controllern nicht, weil Anfragen an sie gerichtet wurden und die vollständige Anwendung eingerichtet wurde.

Eine Sache, die ich erwähnen sollte, ist, dass ich einen Anbieter verwende, um meine Anwendung den Tests zur Verfügung zu stellen. Sollte ich den Guice Application Builder verwenden? Wenn ja, wohin geht das? Die Spieldokumente sind in dieser Hinsicht nicht sehr hilfreich. Hier ist der Anbieter

@Override 
protected FakeApplication provideFakeApplication() { 
    return new FakeApplication(new java.io.File("."), Helpers.class.getClassLoader(), ImmutableMap.of("play.http.router", "router.Routes"), new ArrayList<String>(), null); 
} 

UPDATE:

hier das Update auf den Vorschlag unter

Inside my BaseTest Klasse

@Override 
    protected Application provideApplication() { 
     return new GuiceApplicationBuilder().in(Mode.TEST).build(); 
    } 

Und dann in der Betriebsprüfung Klasse basiert

@Before 
    public void beforeTest() { 
     Injector injector = new GuiceInjectorBuilder().bindings(bind(TagService.class).toInstance(new TagService())).injector(); 
     tagService = injector.instanceOf(TagService.class); 
    } 

Ich bekomme jedoch immer noch Nullzeigerausnahmen, weil das TagRepository nicht injiziert wird.

ANTWORT:

ich diesen etwas falsch zu denken. Wenn Sie Setup der Injektor mit dem Objekt, das Sie injizieren müssen, dann eine Instanz von dem erstellen, werden Sie keine weitere Nullpointerexceptions bekommen

@Before 
public void beforeTest() { 
    Injector injector = new GuiceInjectorBuilder().bindings(bind(TagRepository.class).toInstance(new TagRepository())).injector(); 
    tagService = injector.instanceOf(TagService.class); 
} 
+0

Ich denke, dass Sie vergessen, den Schein des '@ Injected' Repository zu erstellen, und deshalb erhalten Sie die Ausnahme. –

+0

Was wäre der richtige Weg, um dieses Mock zu erstellen? Anwendungsgenerator? Wenn ja, wohin würde das gehen? – Zarathuztra

+0

Wenn Sie Konstruktor oder Parameter-Injektion verwenden, wäre es ziemlich einfach, aber von dem, was Sie zur Verfügung gestellt haben, nehme ich an, dass Sie keine von ihnen verwenden, also werfen Sie einen Blick auf diesen Thread http://StackOverflow.com/Questions/2448013/ How-Test-Guice-Injektionen –

Antwort

6

Wenn Sie WithApplication erstreckt, können Sie protected Application provideApplication() außer Kraft setzen eine Application zurückzukehren gebaut unter Verwendung GuiceApplicationBuilder.

Zum Beispiel (basierend auf this code) können Sie Ihre App erstellen, Bindungen hinzufügen oder überschreiben, usw., und den Modus einstellen. Wenn Sie die Klasse abstrakt machen, wird sie automatisch mit allen untergeordneten Klassen funktionieren.

Untergeordnete Klassen erweitern dann einfach diese Klasse und testen wie gewohnt - alle DI sollten wie bei normaler Ausführung der Anwendung auftreten.

Sie können verschiedene Beispiele davon here

Dies gibt die Grundzüge sehen, was Sie tun müssen. Hoffentlich machen die Dokumente bei https://playframework.com/documentation/2.4.x/JavaTestingWithGuice jetzt ein bisschen mehr Sinn.

+0

Das ist genau das, was ich gesucht habe. Ich werde es heute Abend versuchen und sehen, was passiert – Zarathuztra

+0

Ich habe das versucht und es wirft immer noch NullPointerException. Hab meinen Code in meine Frage eingefügt. Ich folgte den Beispielen, die Sie mir gegeben haben, und vermaß das mit den Inhalten der Play-Dokumentation, aber ich kann den Injektor immer noch nicht richtig arbeiten lassen. – Zarathuztra

+1

Egal, herausgefunden, dass ich das injizierte Repository-Objekt an den Injector binden muss, und dann ein TagService-Objekt daraus erstellen. Du hast mich auf den richtigen Weg gebracht, vielen Dank! – Zarathuztra

Verwandte Themen