2013-08-02 42 views
0

我現在使用Guice進行JSF Web應用程序的JUnit測試。假設我有幾類:如何使用Guice處理多層次注入

class ServiceA 
{ 
    @Inject 
    ServiceB serviceB; 
    //do something using serviceB 
    ... 
} 

interface ServiceB 
{ 
//APIs in ServiceB 
... 
} 

class ServiceBImpl implements ServiceB 
{ 
    @Inject 
    ServiceC serviceC; 
    //do something using serviceC 
    ... 
} 

interface ServiceC 
{ 
//APIs in ServiceC 
... 
} 

class ServiceCImpl implements ServiceC 
{ 
    //do something 
    ... 
} 

現在我用吉斯構建模塊 ServiceA。我的模塊看起來像下面

class ServiceAModule implements Module 
{ 
    @Override 
    public void configure(Binder binder) { 
    binder.bind(ServiceB.class).to(ServiceBImpl.class); 
    } 
} 

而且在我的JUnit測試類,我使用的吉斯創造注射,它看起來像:

public ServiceATest 
{ 

    ServiceA serviceA; 

    @Before 
    public void before() 
    { 
     Injector injector = Guice.createInjector(new ServiceAModule()); 
     serviceA = injector.getInstance(ServiceA.class); 
    } 

    //do the test 
    ... 
} 

現在的問題是ServiceATest一無所知「ServiceC 「,並且它不會被注入到ServiceB中。

當然,我可以建立另一個模塊來介紹ServiceC的ServiceB注入。但是這肯定會破壞代碼分層。如果ServiceC由另一個人開發並且我對ServiceC一無所知怎麼辦?這不應該是一個好的解決方案。

Guice可以處理這種多層次注射嗎?

回答

2

除非您正在進行集成測試,否則不應該進行多層次注射。

在單元測試ServiceATest中,您應該注入ServiceB模擬並且不關心ServiceC和guice模塊。你可以使用mockito的@InjectMocks而不是Guice。

如果您正在進行集成測試,那麼您應該決定在特定測試中涉及哪些組件。測試範圍之外的所有組件都應該模擬,可能您會在測試案例中使用附加ad-hock MockModule來綁定嘲笑的依賴關係。

BTW,而不是使用的getInstance你可以注入你的單元測試裏面豆類,即:

public ServiceATest 
{ 
    @Inject 
    ServiceA serviceA; 

    @Before 
    public void before() 
    { 
     Injector injector = Guice.createInjector(new ServiceAModule()); 
     injector.injectMembers(this); 
    } 
}