2011-12-14 164 views
4

我正在尋找一個解決方案來模擬子類ButtonClicker中的超級調用。模擬/測試超類調用的子類..有可能嗎?

Class Click { 
     public void buttonClick() throws java.lang.Exception { /* compiled code */ }  } 

Class ButtonClicker extends Click { 
    @Override 
    public void buttonClick() throws Exception { 

     super.buttonClick(); 
    } } 
+0

當你問一個問題時,請稍微清楚一點。請詳細說明.... – 2011-12-14 14:28:21

+0

我不能想到一個用例,嘲笑ButtonClicker的'buttonClick'方法不能滿足你的需求 - 你能解釋你的情況嗎? – 2011-12-14 20:09:29

回答

5

使用繼承會降低代碼的可測試性。考慮用delegation代替繼承,並模擬委託。

提取接口IClicker

interface IClicker { 
    void buttonClick(); 
} 

實現ClickerIClicker。在您正在使用第三方代碼工作的情況下,可以考慮使用Adapter Pattern

重寫你的ButtonClicker如下:

class ButtonClicker implements IClicker { 
    Clicker delegate; 

    ButtonClicker(Clicker delegate) { 
     this.delegate = delegate; 
    } 

    @Override 
    public void buttonClick() throws Exception { 
     delegate.buttonClick(); 
    } 

} 

現在只是通過模擬一個構造函數的參數:

Clicker mock = Mockito.mock(Clicker.class); 
// stubbing here 
ButtonClicker buttonClicker = new ButtonClicker(mock); 
+0

感謝您放下代碼,它是試圖覆蓋的遺留代碼,但是現在正在考慮重構它,但有幾個問題。 1. Class Click是第三方代碼,請你解釋爲什麼我應該考慮適配器而不是委派。我甚至在代表團看到,我只需要修改我的ButtonClicker類來實現接口。 2. ButtonClicker實際上是一個動作bean(seam組件),它直接從UI中調用,我想知道如何/何時調用一個參數ButtonClicker構造函數以便委託調用類Click方法? – 2011-12-14 18:32:39

3

答案沒有。模擬只是一個簡單的接口實現。 (我的意思是API接口,而不是特定的Java關鍵字意義。)因此它不知道任何實現細節,比如哪個類實際實現了這個功能(本質上沒有功能)。

你可以在一個真實物體上創建一個'間諜',它可以讓你嘲笑一些方法而不是其他的方法,但是這也不會讓你嘲笑類的超級方法,因爲你選擇的方法嘲笑通常由簽名來選擇,這對於子類和超類都是相同的。