2011-12-04 49 views
4

抽象類的如何測試protected的方法我也有這樣的情況 - 我有接口(比如MyInterface)和簡單的部分實現(AbstractMyInterface)。後者增加了一些我想測試的受保護的方法。使用JUnit和JMock的

目前我只是手工編寫延伸AbstractMyInterface和出口的保護方法爲公共模仿對象。有沒有更簡單的方法 - 例如使用JMock +腳本?

回答

6

我無法看到使用JUnit測試protected方法任何問題。只要測試包結構反映源樹結構,除私有方法外,測試可見。

當然,如果執行測試是抽象的,你必須自己測試下創建類的子類正常(或者,如果你的目的更適合的通過一些嘲諷庫這樣做)。同樣在這種情況下,不需要爲調用受保護的可見性方法創建一層公共方法。只有私人方法這個策略不起作用。但無論如何,經常需要測試私有方法是設計問題的標誌。

例如: 要測試的類位於src/mypackage/AbstractClass.java package mypackage;

/** This could as well implement some interface, 
    but that does not change a thing */ 
public class AbstractClass { 
    protected int returnsOne() { 
     return 1; 
    } 
} 

和測試它位於測試/ mypackage中/ AbstractClassTest.java

package mypackage; 

import org.junit.Test; 

import static junit.framework.Assert.assertEquals; 

public class AbstractClassTest { 
    @Test 
    public void returnsOneReturnsOne() { 
     AbstractClass instanceToTest = new AbstractClassTestable(); 
     assertEquals(1, instanceToTest.returnsOne()); 
    } 
} 

/** This is needed, because we cannot construct abstract class directly */ 
class AbstractClassTestable extends AbstractClass { 
} 
+0

除了我有越來越多的未使用的存根在測試中,沒有任何問題。 –

0

可以使抽象測試用例的接口(或抽象類)。然後做一個具體的測試用例,擴展你的抽象測試用例,以便爲你的接口(或抽象類)的每個具體實現。

3

只是一個建議,

如果我們不測試受保護的方法,我們可以使用哪些公有方法來覆蓋這些保護方法?

如果不是,是不是因爲受保護的方法太複雜的,重構提取複雜的事情到一個新的對象,它提供的公共接口,而舊的對象只是一個私有對象在一些公共方法。

測試將在以後的新對象上進行。

blog post可能會有所幫助。

+0

否 - 受保護的方法非常簡單,但它們都是公開API(簡單發佈/訂閱模型的一部分)。該部分由公共方法使用,但測試它是否有效我需要訪問受保護的部分。作爲後 - 雖然我同意私人方法不應該被測試,但受保護的方法被其他人使用。 –

+0

公共方法需要訪問由受保護方法包裝的公共API,看起來這個類有兩個任務。設計一個包裝類來隱藏公共API,並設計一個用戶類來使用包裝提供的服務。所以,即使API將要改變,也不會損害可能充滿邏輯的用戶類。我從單元測試中學習了十年雜亂無章的C代碼,如果它很難做單元測試,離開它,重構代碼是一種簡單而好的RoI方法。 –

+0

Chris Zheng:你可以證明對於使用發佈訂閱的簡單代碼嗎?公共方法應該只註冊/註銷觀察者,而受保護的方法只是觸發各種事件(循環觀察者設置和發送通知事件)。我沒有看到解決方案會按照您描述的方式進行,並且不會違反KISS規則。 –