2017-10-12 116 views
3

,如果我創造,我想在一個特定的功能,使用匕首可以說,子組件:匕首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

這很容易對原匕首,但沒有使用匕首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

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)

如果需要完整的代碼,離開發表評論我將爲此創造要點。