Quindi ho cercato di capirlo da solo tramite documentazione, ma non riesco ad arrivare da nessuna parte.Guice, DI e test di unità in gioco 2.4
Ho alcune semplici impostazioni di binding DI in una classe di servizio che crea un oggetto repository. Semplice. Tuttavia, quando eseguo questo in modalità test, @Inject non fa nulla e l'oggetto repository non viene mai istanziato.
@Inject
TagRepository tagRepository;
Così sulla linea in cui il suo uso, in modalità di prova, abbiamo naturalmente ottenere un NullPointerException
tagRepository.tagExistsByName(tag);
Questa bolle su nel mio test in questo modo:
[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)
La mia domanda è, come posso configurare la mia applicazione per utilizzare gli iniettori Guice in modalità test? Non avevo questo problema con i miei controller perché le richieste venivano effettivamente fatte a loro, impostando l'applicazione completa.
Una cosa che dovrei menzionare è che sto usando un provider per fornire la mia app ai test. Dovrei usare il costruttore di applicazioni Guice? Se è così, dove va? I documenti di gioco non sono molto utili a tale riguardo. Qui è il fornitore
@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:
Ecco l'aggiornamento basato su suggerimento di sotto
Dentro la mia classe BaseTest
@Override
protected Application provideApplication() {
return new GuiceApplicationBuilder().in(Mode.TEST).build();
}
E poi nella classe di test di servizio
@Before
public void beforeTest() {
Injector injector = new GuiceInjectorBuilder().bindings(bind(TagService.class).toInstance(new TagService())).injector();
tagService = injector.instanceOf(TagService.class);
}
Tuttavia, sto ancora ricevendo eccezioni del puntatore nullo perché TagRepository non viene iniettato.
RISPOSTA:
Stavo pensando a questo un po 'sbagliato. Se si imposta l'iniettore con l'oggetto è necessario iniettare, quindi creare un'istanza da quello, non riceverai più NullPointerExceptions
@Before
public void beforeTest() {
Injector injector = new GuiceInjectorBuilder().bindings(bind(TagRepository.class).toInstance(new TagRepository())).injector();
tagService = injector.instanceOf(TagService.class);
}
Penso che si dimentichi di creare il mock del repository '@ Injected' ed è per questo che si ottiene l'eccezione. –
Quale sarebbe il modo corretto di creare quel finto essere? Costruttore di applicazioni? Se sì, dove andrebbe? – Zarathuztra
Se si sta usando il constructor o il parametro injection, sarebbe abbastanza facile, ma da quello che hai fornito suppongo che tu non ne usi nessuno, quindi dai un'occhiata a questa discussione http://stackoverflow.com/questions/2448013/ how-test-guice-inections –