2015-08-29 67 views
11

所以我一直試圖通過文檔自己弄清楚這一點,但我沒有得到任何地方。Guice,DI和單元測試在玩2.4

我已經在創建存儲庫對象的服務類中設置了一些簡單的DI綁定。簡單。但是,當我在測試模式下運行它時,@Inject什麼也不做,並且存儲庫對象從不實例化。

@Inject 
TagRepository tagRepository; 

所以在這裏它的使用,在測試模式下的線,我們當然得到一個NullPointerException

tagRepository.tagExistsByName(tag); 

這冒泡到我的測試,像這樣:

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

我的問題是,如何配置我的應用程序在測試模式下使用Guice噴嘴?我的控制器沒有這個問題,因爲實際上他們正在向他們提出請求,建立了完整的應用程序。

我應該提到的一件事就是我正在使用提供者來提供我的應用程序進行測試。我應該使用Guice應用程序構建器嗎?如果是這樣,那麼去哪裏?劇本文件在這方面不是很有幫助。這裏是提供

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

這是基於以下

建議裏面我BaseTest類

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

然後在服務測試類更新

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

但是,我仍然收到空指針異常,因爲TagRepository沒有被注入。

回答:

我在想這個有點不對。如果你安裝你需要注入目標的噴射器,然後創建從一個實例,如果你伸出你WithApplication不會得到任何更多NullPointerExceptions的

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

我認爲你忘了創建'@ Injected'版本庫的模擬,這就是爲什麼你會得到異常。 –

+0

創建該模擬的正確方法是什麼?應用程序構建器?如果是這樣,那去哪裏? – Zarathuztra

+0

如果你正在使用構造函數或參數注入,它會相當容易,但從你提供的東西我猜你沒有使用任何一個,所以看看這個線程http://stackoverflow.com/questions/2448013/ how-test-guice -injection –

回答

6

,您可以覆蓋protected Application provideApplication()返回一個Application使用GuiceApplicationBuilder建成。

例如(基於this code),你可以創建你的應用中添加或覆蓋綁定等,並設置模式。如果您將類抽象化,它將自動與所有子類一起工作。

public abstract class AbstractFakeApplicationTest extends WithApplication 
{ 
    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractFakeApplicationTest.class); 

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

    @Override 
    public void startPlay() 
    { 
     super.startPlay(); 
     // mock or otherwise provide a context 
     Http.Context.current.set(new Http.Context(1L, 
                Mockito.mock(RequestHeader.class), 
                Mockito.mock(Http.Request.class), 
                Collections.<String, String>emptyMap(), 
                Collections.<String, String>emptyMap(), 
                Collections.<String, Object>emptyMap())); 
    } 

    public Http.Context context() 
    { 
     return Http.Context.current.get(); 
    } 
} 

子類則只需擴展此類和試驗正常 - 當你正常運行的應用程序它應該發生的所有DI。

你可以看到它的here

各種例子這給了基本的輪廓爲你需要做什麼。希望https://playframework.com/documentation/2.4.x/JavaTestingWithGuice的文檔現在會更有意義。

+0

這完全是我在找的東西。今晚我會給它一個鏡頭,看看會發生什麼 – Zarathuztra

+0

我試過了,它仍然拋出NullPointerException。在我的問題中粘貼了我的代碼。我遵循了你給我的例子,並將其與Play文檔上的內容進行了關聯,但仍然無法使注入器正常工作。 – Zarathuztra

+1

不要緊,找出我必須將注入的資源庫對象綁定到注入器,然後從中創建一個TagService對象。你指出我走對了路,非常感謝! – Zarathuztra