2012-10-04 51 views
-1

我已經切換到MVP架構並試圖對其進行測試。我對如何構建Presenter有一些疑問。MVP,測試和私有方法

public class Presenter 
{ 
    public void onResume() 
    { 
     doA(); 
     doB(); 
     doC(); 
    } 

    protected void doA() {}; 
    protected void doB() {}; 
    protected void doC() {}; 
} 

public class MyScreen implements MyScreenView 
{ 
    private Presenter presenter; 

    public MyScreen() 
    { 
     presenter = new Presenter(this); 
    } 

    public OnResume() 
    { 
     presenter.OnResume(); 
    } 
} 

在上面的代碼中,當該視圖被恢復時,視圖只是調用呈現的onResume()。演示者在內部調用3個方法doA(),doB()和doC()來完成它所要做的任何事情。

或者,我可以叫DOA(),出生日期()和DOC()在視圖中直接像這樣:

public class Presenter 
{ 
    public void doA() {}; 
    public void doB() {}; 
    public void doC() {}; 
} 

public class MyScreen implements MyScreenView 
{ 
    private Presenter presenter; 

    public MyScreen() 
    { 
     presenter = new Presenter(this); 
    } 

    public OnResume() 
    { 
     presenter.doA(); 
     presenter.doB(); 
     presenter.doC(); 
    } 
} 

我的問題是,它更容易爲我測試第二個解決方案,因爲主持人完全分解成3個獨立的公共個人責任方法,我可以單獨爲doA,doB和doC編寫測試,而不是針對解決方案1的演示者.onResume()方法的單個測試。

在第一個解決方案,我必須爲onResume()編寫測試,它負責調用這3個方法。這意味着它更難測試,因爲它比調用其他私有函數的函數更容易測試個別責任的小函數。然而,第二種解決方案並不像我想的那樣是一個很好的MVP,因爲它似乎知道主講人在做什麼,只是不讓主持人在第一個解決方案的onResume()方法中執行它應該做的事情。

+0

絕不要在stackoverflow上尋求意見。它是保證解決問題的關鍵。當然,所有值得高興或低估的都是意見,但這是一個不同的故事。 –

回答

1

如果你改變你的自選類

public class MyScreen implements MyScreenView 
{ 
    private presenter; 

    public MyScreen() 
    { 
     presenter = new Presenter(); 
    } 

    public MyScreen(Presenter p) 
    { 
     presenter = p; 
    } 

    public OnResume() 
    { 
     presenter.OnResume(); 
    } 
} 

那麼你有一個生產構造函數創建一個新的演示和測試一個方便的構造函數,因此你可以用模擬演示實例化。我喜歡的Mockito(代碼從存儲器中,以便...)

Presenter mockP = Mock(Presenter.class); 
MyScreen target = new MyScreen(mockP); 
target.OnResume(); 
verify(mockP).doA(); 
verify(mockP).doB(); 
verify(mockP).doC(); 

在這裏,您創建一個模擬演示新的自選畫面。當你在各種方法上調用驗證時,如果該方法從未在模擬中調用過,則測試將失敗。因此,您實際上正在編寫一個測試,如果您在MyScreen類中調用OnResume,則會觸發doA,doB和doC的演示者字段。

您可以在驗證調用方法時指定期望的參數。你可以對mockP的方法進行存根化,以便在特定場景下返回已知的結果。


順便

public OnResume() 
    { 
     presenter.OnResume(); 
    } 

是恕我直言,你的兩個選項是更好的選擇,因爲這樣你可以改變presenter.OnResume()方法做什麼,而不必更改自選畫面類。

+0

hrm ....如果doA()是私有的,我可以調用verify(mockP).doA()嗎? – SpecialEd

+0

不,那麼你會驗證Presenter的onResume方法被調用。當你測試Presenter類的時候,你可以測試一下,如果onResume被稱爲這三個方法的東西,那麼......做完了。我有一種感覺,PowerMock可以處理私有方法,但我從來沒有使用過PowerMock,所以很容易出錯 –

1

首先,請在我的屏幕類

public class MyScreen implements MyScreenView 
{ 
    private presenter; 

    public MyScreen() 
    { 
     presenter = this(new Presenter()); 
    } 

    public MyScreen(Presenter p) 
    { 
     presenter = p; 
    } 

    public OnResume() 
    { 
     presenter.OnResume(); 
    } 
} 

主持人注射現在,您可以通過注入模擬測試自選的行爲。

Presenter mockP = Mock(Presenter.class); 
MyScreen target = new MyScreen(mockP); 
target.OnResume(); 
verify(mockP).doA(); 
verify(mockP).doB(); 
verify(mockP).doC(); 

在一個完全獨立的測試可以測試主持人:

Presenter presenter = new Presenter(); 
presenter.onResume(); 
assertEquals("some State that should be true after calling on resume", presenter.getSomeMagicState()); 

不要測試的onResume調用DOA,DOB和文檔,測試方法的行爲,通過檢查angainst的狀態主持人。

如果任何doX的操作變得複雜,將其提取到一個單獨的類中,測試它,將其注入演示者並測試它被調用。