注入组件
首先,创建一个静态类来充当 Activity 的工厂。我的看起来有点像这样:
public class ActivityComponentFactory {
private static ActivityComponentFactory sInstance;
public static ActivityComponentFactory getInstance() {
if(sInstance == null) sInstance = new ActivityComponentFactory();
return sInstance;
}
@VisibleForTesting
public static void setInstance(ActivityComponentFactory instance) {
sInstance = instance;
}
private ActivityComponentFactory() {
// Singleton
}
public ActivityComponent createActivityComponent() {
return DaggerActivityComponent.create();
}
}
然后就做ActivityComponentFactory.getInstance().createActivityComponent().inject(this);
在您的活动中。
为了进行测试,您可以在创建活动之前替换方法中的工厂。
提供模拟
正如 @EpicPandaForce 的回答所明确的,这样做官方支持目前的方式涉及大量样板和复制/粘贴代码。 Dagger 2 团队需要提供一种更简单的方法来部分重写模块。
在他们这样做之前,这是我的非正式方式:只需扩展模块即可.
假设您想用模拟替换 ListViewPresenter。假设您有一个 PresenterModule,如下所示:
@Module @ActivityScope
public class PresenterModule {
@ActivityScope
public ListViewPresenter provideListViewPresenter() {
return new ListViewPresenter();
}
@ActivityScope
public SomeOtherPresenter provideSomeOtherPresenter() {
return new SomeOtherPresenter();
}
}
您可以在测试设置中执行此操作:
ActivityComponentFactory.setInstance(new ActivityComponentFactory() {
@Override
public ActivityComponent createActivityComponent() {
return DaggerActivityComponent.builder()
.presenterModule(new PresenterModule() {
@Override
public ListViewPresenter provideListViewPresenter() {
// Note you don't have to use Mockito, it's just what I use
return Mockito.mock(ListViewPresenter.class);
}
})
.build();
}
});
...还有它正常工作!
请注意,您不必包括@Provides
上的注释@Override
方法。事实上,如果您这样做,Dagger 2 代码生成将会失败。
这是可行的,因为模块只是简单的工厂 - 生成的组件类负责缓存作用域实例的实例。这@Scope
注释由代码生成器使用,但在运行时无关。