[英]Field injection in unit tests with Dagger 2
正如Dagger文檔中所建議的那樣,對於單元測試,我們根本不需要涉及Dagger,並且對於提供的示例,它是有意義的:
class ThingDoer {
private final ThingGetter getter;
private final ThingPutter putter;
@Inject ThingDoer(ThingGetter getter, ThingPutter putter) {
this.getter = getter;
this.putter = putter;
}
String doTheThing(int howManyTimes) { /* … */ }
}
使用這個類結構,單元測試很簡單,只需模擬getter
和putter
,將它們作為構造函數參數傳遞,指示mockito在與任何這些對象交互時返回什么,然后在doTheThing(...)
上進行斷言。
我在測試中苦苦掙扎的地方是我必須對類似於以下結構的類進行單元測試:
class ThingDoer {
@Inject
ThingGetter getter;
@Inject
ThingPutter putter;
@Inject
ThingMaker maker;
@Inject
// other 10 objects
public ThingDoer() {
App.getThingComponent().inject(this);
}
String doTheThing(int howManyTimes) { /* … */ }
}
如您所見,我不再使用構造函數注入,而是使用字段注入。 主要原因是構造函數中沒有太多參數。
當使用字段注入提供所有依賴ThingDoer
時,有沒有辦法在ThingDoer
注入模擬依賴ThingDoer
?
對於現場注入,您可以創建在單元測試中使用的組件和模塊。
假設您有單元測試類ThingDoerTest
,您可以使組件向ThingDoerTest
注入依賴ThingDoerTest
而不是ThingDoer
,模塊提供模擬對象而不是真實對象。
在我的項目中, HomeActivity
有一個現場注入HomePresenter
。 以下代碼是一些片段。 希望代碼可以給你一些想法。
@RunWith(AndroidJUnit4.class)
public class HomeActivityTest implements ActivityLifecycleInjector<HomeActivity>{
@Rule
public InjectorActivityTestRule<HomeActivity> activityTestRule = new InjectorActivityTestRule<>(HomeActivity.class, this);
@Inject
public HomePresenter mockHomePresenter;
@Override
public void beforeOnCreate(HomeActivity homeActivity) {
Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation();
MyApplication myApplication = (MyApplication) instrumentation.getTargetContext().getApplicationContext();
TestHomeComponent testHomeComponent = DaggerHomeActivityTest_TestHomeComponent.builder()
.appComponent(myApplication.getAppComponent())
.mockHomeModule(new MockHomeModule())
.build();
testHomeComponent.inject(HomeActivityTest.this);
homeActivity.setHomeComponent(testHomeComponent);
}
@Test
public void testOnCreate() throws Exception {
verify(mockHomePresenter).start();
}
@ActivityScope
@Component(
dependencies = {
AppComponent.class
},
modules = {
MockHomeModule.class
}
)
public interface TestHomeComponent extends HomeComponent {
void inject(HomeActivityTest homeActivityTest);
}
@Module
public class MockHomeModule {
@ActivityScope
@Provides
public HomePresenter provideHomePresenter() {
return mock(HomePresenter.class);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.