我的 Activity 中有一个作用域依赖项,我想用一些模拟来测试该 Activity。我已经阅读了不同的方法,建议在测试期间用测试组件替换应用程序组件,但我想要的是替换 Activity 组件。
例如,我想在我的 MVP 设置中针对模拟演示者测试 Activity。
我认为通过在 Activity 上调用 setComponent() 来替换组件是行不通的,因为 Activity 依赖项已经通过字段注入(inject)注入(inject),因此在测试期间,将使用真实对象。
我该如何解决这个问题? Dagger1 呢?是否有同样的问题?
最佳答案
注入(inject)组件
首先,您创建一个静态类作为您的 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();
}
}
然后只需在您的 Activity 中执行 ActivityComponentFactory.getInstance().createActivityComponent().inject(this);
。
为了测试,您可以在创建 Activity 之前替换方法中的工厂。
提供模拟
正如@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();
}
});
...它正常工作!
请注意,您不必在 @Override
方法中包含 @Provides
注释。事实上,如果这样做,Dagger 2 代码生成将会失败。
这是可行的,因为模块只是简单的工厂——生成的组件类负责缓存作用域实例的实例。 @Scope
注释由代码生成器使用,但在运行时无关紧要。
关于android - 如何使用 Dagger2 将 Activity 范围内的依赖项替换为模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32281503/