如果我创建了一个子组件,我想用 Dagger 在特定功能中使用,让我们说:
@TransactionsActivityScope
@Subcomponent(modules = {TransactionsModule.class})
public interface TransactionsComponent {
TransactionsManager provideTransactionsManager();
void inject(TransactionsFragment transactionsFragment);
void inject(TransactionsFilterActivity transactionsFilterActivity);
}
我在主应用程序组件中添加了一个加号:
TransactionComponent plusTransactionSubcomponent(TransactionModule transactionModule);
并在 fragment 中使用它: 公共(public)类 TransactionsFragment { .. .. ..
@Override
protected void setupGraph(DaggerAppGraph graph) {
graph.plusTransactionsSubcomponent(new TransactionModule()).inject(this);
}
}
在 Espresso 测试中覆盖此子组件的正确方法是什么。 对于组件和组件依赖性,直接编写一个 TestAppComponent 来扩展“原始”组件并在其中插入 MockModules 是很直接的,但是如何使用子组件干净利落地做到这一点?
我还看了一下 Dagger AndroidInjector.inject(this);组件和 Activity 组件的解决方案是相似的,但我认为没有办法对子组件和 fragment 进行干净的处理。 我认为编写方法并覆盖 Activity/Fragments 组件 setter 并在那里进行覆盖是次优的。 我错过了什么吗?
最佳答案
这在原来的 Dagger 上很容易,但使用 Dagger 2 就不行。然而,这里是解决方案:创建一个模拟的 flavor 和一个具有完全相同的类名、文件名和位置的模拟模块。现在使用模拟风格运行您的 UI 测试。
你可以在我的test project中看到它是如何完成的。
我在我的应用中使用了真正的模块。位于 src/prod/.../ContentRepositoryModule.java
我在测试时使用模拟模块:位于 src/mock/.../ContentRepositoryModule.java
然后我的模拟模块引用 FakeContentRepository,就像您计划的那样。
在build.gradle中:
flavorDimensions "api", "mode"
productFlavors {
dev21 {
// min 21 has faster build times, also with instant build
minSdkVersion 21
dimension "api"
}
dev16 {
minSdkVersion 16
dimension "api"
}
mock {
dimension "mode"
}
prod {
minSdkVersion 16
dimension "mode"
}
}
// remove mockRelease:
android.variantFilter { variant ->
if (variant.buildType.name == 'release'
&& variant.getFlavors().get(1).name == 'mock') {
variant.setIgnore(true);
}
}
又是:this test project说明一切。
关于android - Dagger 2 Android 子组件覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46711534/