匕首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中看到它是如何完成的。

然后我嘲笑模块引用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展示这一切。

+0

是的,这是一个选项,但我认为它是次优的我宁愿有测试代码只在androidTest沙发我已经设法做到这一点重写测试活动的组件,但对于子组件我仍然没有任何干净的代码灵感 – originx

+0

如果您找到更简单的解决方案,请告诉我。上述方法的主要/唯一缺点是文件夹的管理。 – Frank

在我们的应用程序中,我们使用附加包装来管理名为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)

如果需要完整的代码,离开发表评论我将为此创造要点。