如果我创建一个我想在dagger特定功能中使用的子组件,请说:
@TransactionsActivityScope
@Subcomponent(modules = {TransactionsModule.class})
public interface TransactionsComponent {
TransactionsManager provideTransactionsManager();
void inject(TransactionsFragment transactionsFragment);
void inject(TransactionsFilterActivity transactionsFilterActivity);
}
我在主应用组件中添加了一个加号:
TransactionComponent plusTransactionSubcomponent(TransactionModule transactionModule);
并在片段中使用它: public class TransactionsFragment { .. .. ..
@Override
protected void setupGraph(DaggerAppGraph graph) {
graph.plusTransactionsSubcomponent(new TransactionModule()).inject(this);
}
}
在Espresso测试中覆盖此子组件的正确方法是什么。 对于组件和组件依赖关系,您可以直接编写一个扩展“原始”组件的TestAppComponent并在其中打出MockModule,但如何使用子组件干净地完成此操作?
我还看了一下Dagger的AndroidInjector.inject(这个);组件和活动组件的解决方案是类似的,但我认为没有办法干净地为子组件和片段做到这一点。 我认为编写方法并覆盖Activity / Fragments组件setter并在那里进行覆盖是不理想的。 我错过了什么吗?
答案 0 :(得分:2)
这在原始的Dagger上很容易,但是没有使用Dagger 2.但是,这里有解决方案:创建一个模拟的风格和一个具有完全相同的类名,文件名和位置的模拟模块。现在使用模拟的味道运行你的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显示一切。
答案 1 :(得分:0)
在我们的应用程序中,我们使用额外的包装器来管理名为ComponentStorage
的子组件范围。我们的Application
创建此对象,TestApplication
会覆盖它并返回TestComponentStorage
。因此,我们可以轻松覆盖方法plusTransactionSubcomponent
并使用模拟模块返回组件。
public class ComponentStorage {
protected TransactionComponent transactionComponent;
protected AppGraph graph;
public ComponentStorage() {
graph = buildGraph();
}
public TransactionComponent plusTransactionSubcomponent(TransactionModule transactionModule) {
if(transactionComponent == null) {
transactionComponent = graph.plusTransactionsSubcomponent(new TransactionModule());
}
return transactionComponent;
}
public AppGraph buildGraph() {
return DaggerAppGraph.create();
}
// to manage scope manually
public void clearTransactionSubcomponent() {
transactionComponent = null;
}
}
public class TestComponentStorage extends ComponentStorage{
@Override
public TransactionComponent plusTransactionSubcomponent(TransactionModule transactionModule) {
if(transactionComponent == null) {
// mocked module
transactionComponent = graph.plusTransactionsSubcomponent(new TestTransactionModule());
}
return transactionComponent;
}
}
在客户端代码中,您将使用它componentStorage.plusTransactionsSubcomponent(new TransactionModule()).inject(this)
如果您需要完整的代码,请留下评论我将为此创建要点。