2015-08-29 34 views
11

Tak więc próbowałem to sobie samemu zilustrować poprzez dokumentację, ale nigdzie się nie dostaję.Testy Guice, DI i Unit w grze 2.4

Mam kilka prostych konfiguracji wiązań DI w klasie usług, która tworzy obiekt repozytorium. Prosty. Jednak gdy uruchomię to w trybie testowym, @Inject nic nie zrobi i obiekt repozytorium nigdy nie zostanie utworzony.

@Inject 
TagRepository tagRepository; 

Więc na linii, gdzie jest zastosowanie, w trybie testowym, my oczywiście uzyskać NullPointerException

tagRepository.tagExistsByName(tag); 

pęcherzyki To się w moim teście tak:

[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) 

moje pytanie jak skonfigurować swoją aplikację, aby używać wtryskiwaczy Guice w trybie testowym? Nie miałem tego problemu z moimi kontrolerami, ponieważ do nich właśnie wysyłano wnioski, konfigurując pełną aplikację.

Jedną z rzeczy, o których powinienem wspomnieć, jest to, że korzystam z usług dostawcy, aby udostępnić moją aplikację do testów. Czy powinienem używać kreatora aplikacji Guice? Jeśli tak, to gdzie to jest? Dokumenty do gry nie są zbyt pomocne w tym względzie. Tutaj jest dostawcą

@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:

Oto aktualizacja na podstawie sugestii poniżej

Wewnątrz mojej klasie BaseTest

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

A potem w klasie Testing Service

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

Jednak nadal otrzymuję wyjątki wskaźnika pustego, ponieważ TagRepository nie jest wstrzykiwany.

ODPOWIEDŹ:

Myślałam o tym nieco racji. Jeśli konfiguracja wtryskiwacz z obiektu trzeba wstrzykiwać, a następnie utworzyć instancję z tym, że nie będzie żadnych więcej NullPointerExceptions

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

Myślę, że zapomniałeś stworzyć makietę repozytorium '@ Injected' i dlatego otrzymujesz wyjątek. –

+0

Jaki byłby właściwy sposób tworzenia tego makiety? Konstruktor aplikacji? Jeśli tak, to gdzie by to poszło? – Zarathuztra

+0

Jeśli używasz konstruktora lub iniekcji parametru, byłoby to dość łatwe, ale z tego, co masz pod warunkiem Zgaduję, że nie używasz żadnego z nich, więc spójrz na ten wątek http://stackoverflow.com/questions/2448013/ how-test-guice-injections –

Odpowiedz

6

Jeśli rozszerzenie WithApplication można przesłonić protected Application provideApplication() do zwracania Application zbudowany przy użyciu GuiceApplicationBuilder.

Na przykład (na podstawie this code) można utworzyć aplikację, dodać lub przesłonić wiązania itp. I ustawić tryb. Jeśli sprawisz, że klasa będzie abstrakcyjna, będzie działać automatycznie z wszystkimi klasami dla dzieci.

Klasy dzieci następnie rozszerzają tę klasę i testują jak zwykle - wszystkie DI powinny występować tak, jak podczas normalnej pracy aplikacji.

można zobaczyć różne przykłady nim here

Daje to ogólny zarys tego, co trzeba zrobić. Mam nadzieję, że dokumenty o numerze https://playframework.com/documentation/2.4.x/JavaTestingWithGuice będą miały teraz większy sens.

+0

To jest dokładnie to, czego szukałem. Dam ci dzisiaj szansę i zobaczę, co się stanie – Zarathuztra

+0

Próbowałem tego i nadal rzuca NullPointerException. Wkleiłem mój kod w moje pytanie. Podążyłem za przykładami, które mi dałeś, i powiązałem to z dokumentami Play, ale nadal nie mogę zmusić wtryskiwacza do prawidłowego działania. – Zarathuztra

+1

Nieważne, zorientowałem się, że muszę powiązać wstrzyknięty obiekt repozytorium z Injektorem, a następnie utworzyć z tego obiekt TagService. Wskazałeś mi właściwą drogę, wielkie dzięki! – Zarathuztra