匕首2的Android子组件覆盖
,如果我创造,我想在一个特定的功能,使用匕首可以说,子组件:匕首2的Android子组件覆盖
TransactionComponent plusTransactionSubcomponent(TransactionModule transactionModule);
:
@TransactionsActivityScope
@Subcomponent(modules = {TransactionsModule.class})
public interface TransactionsComponent {
TransactionsManager provideTransactionsManager();
void inject(TransactionsFragment transactionsFragment);
void inject(TransactionsFilterActivity transactionsFilterActivity);
}
我有一个加号添加它的主要的应用程序组件
,并在该片段中使用它: 公共类TransactionsFragment { .. .. ..
@Override
protected void setupGraph(DaggerAppGraph graph) {
graph.plusTransactionsSubcomponent(new TransactionModule()).inject(this);
}
}
在Espresso测试中重写此子组件的正确方法是什么? 对于组件和组件的依赖关系,您只需编写一个扩展“原始”组件并在其中打开MockModules的TestAppComponent即可,但如何使用Subcomponents干净地完成此操作?
我也看了一下Dagger AndroidInjector.inject(this);组件和活动组件的解决方案是相似的,但我认为无法为子组件和碎片干净地完成它。 我认为编写方法并重写Activity/Fragments组件设置器并在其中进行重写会是不理想的。 我错过了什么吗?
这很容易对原匕首,但没有使用匕首2。然而,这里是解决方案:创建一个嘲笑味道和完全相同的类名,文件名和位置的嘲笑模块。现在使用嘲弄的风味运行你的UI测试。
你可以在我的test project中看到它是如何完成的。
我在我的应用程序中使用真正的模块。位于SRC/PROD /.../ ContentRepositoryModule.java
我用嘲笑模块时测试:位于SRC /模拟/.../ 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展示这一切。
在我们的应用程序中,我们使用附加包装来管理名为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)
如果需要完整的代码,离开发表评论我将为此创造要点。
是的,这是一个选项,但我认为它是次优的我宁愿有测试代码只在androidTest沙发我已经设法做到这一点重写测试活动的组件,但对于子组件我仍然没有任何干净的代码灵感 – originx
如果您找到更简单的解决方案,请告诉我。上述方法的主要/唯一缺点是文件夹的管理。 – Frank