2009-07-03 89 views
13

我目前正在嘗試爲小型圖書館建立一套或多或少的完整單元測試。由於我們希望允許不同的實現存在,我們希望這組測試是(a)通用的,以便我們可以重新使用它來測試不同的實現,並且(b)儘可能完整。對於(b)部分,我想知道是否有任何用於測試枚舉類型的最佳做法。所以例如我有一個枚舉如下:如何測試枚舉類型?

public enum Month { 
    January, 
    February, 
    ... 
    December; 
} 

這裏我想確保所有的枚舉類型真的存在。這甚至是必要的嗎?目前我使用Hamcrests assertThat像下面的例子:

assertThat(Month.January, is(notNullValue())); 

一個失蹤「一月」枚舉會導致其中一個可以通過創建缺少的枚舉類型確定一個編譯時錯誤。

我使用Java在這裏,但如果你的答案是不同的語言,我不介意..

編輯:

由於mkato和馬克·希思雙雙指出,測試可枚舉沒有必要,因爲編譯器在您使用不存在的枚舉類型時不會編譯。但我仍然想測試這些枚舉,因爲我們想構建一個獨立的TCK類test.jar,它將在不同的實現上運行相同的測試。所以我的問題更像是:什麼是測試枚舉類型的最好方法?

想着它之後多一點,我改變了Hamcrest聲明以上:

assertThat(Month.valueOf("January"), is(notNullValue())); 

這種說法現在拋出一個NPE月份的時候是不是有(還)。這種方法有什麼問題嗎?

回答

17

對於枚舉,我只在他們實際上有方法的時候才測試它們。如果它是一個純粹的純數值枚舉,就像你的例子,我會說不要打擾。

但是,由於您熱衷於測試它,因此使用第二種方法比第一種方法好得多。第一個問題是,如果您使用IDE,則枚舉上的任何重命名都會重命名測試類中的那些。

+0

我有一個枚舉,有一個方法,我想測試,我是單元測試的新手,無法找出一種方法來編寫該方法的測試用例,請您提供一個示例或幫助做到這一點。 – dirtydexter 2014-10-31 12:16:19

+0

如果「assertThat(Month.January,is(notNullValue()));」在OP的問題中,對於你來說還不夠,我認爲你最好把它當作一個單獨的問題,並提供一個你想要測試的例子。聽起來像你可能需要幫助JUnit本身。 – aberrant80 2014-11-03 02:42:08

3

如果您使用一切都在你的代碼的幾個月,你的IDE不會讓你編譯,所以我覺得你不需要單元測試。

但是,如果你使用的是他們與反思,即使你刪除一個月內,它將編譯,所以它是有效的把一個單元測試。

+0

單元測試不知道你的月份將如何使用,甚至不知道它們將來如何使用。這意味着您應該爲它們包含單元測試,即使應用程序在所有月份不存在的情況下都不會編譯。注意事項:確保你的複雜對象被單元測試覆蓋,然後擔心簡單的問題(比如沒有方法的枚舉)。 – 2017-05-07 09:00:07

4

通常我會說這是矯枉過正,但偶爾會有編寫枚舉單元測試的原因。

有時分配給枚舉成員的值必須永遠不會改變或傳統的裝載持久數據將失敗。同樣,顯然未使用的成員不能被刪除。單元測試可以用來防止開發人員進行更改而不會意識到這些影響。

8

我同意aberrant80

對於枚舉,我只在他們實際上有方法時才測試它們。 如果這是一個純粹的純數值枚舉像你的例子,我會說不要 麻煩。

但是,由於您熱衷於測試它,因此使用第二個選項 要比第一個選項好得多。第一個問題是,如果您使用IDE, 中的任何重命名都會重命名您的測試類中的 。

我將通過添加單元測試來擴展Enum可能非常有用。如果您在大型代碼庫中工作,則編譯時間開始增加,單元測試可以成爲驗證功能的更快方式(測試只構建它們的依賴關係)。另一個非常大的優勢是其他開發人員無法無意地更改代碼的功能(對於非常大的團隊來說是一個巨大的問題)。

對於所有的測試驅動開發,圍繞Enums方法的測試減少了代碼庫中的錯誤數量。

簡單的例子

public enum Multiplier { 
    DOUBLE(2.0), 
    TRIPLE(3.0); 

    private final double multiplier; 

    Multiplier(double multiplier) { 
     this.multiplier = multiplier; 
    } 

    Double applyMultiplier(Double value) { 
     return multiplier * value; 
    } 

} 

public class MultiplierTest { 

    @Test 
    public void should() { 
     assertThat(Multiplier.DOUBLE.applyMultiplier(1.0), is(2.0)); 
     assertThat(Multiplier.TRIPLE.applyMultiplier(1.0), is(3.0)); 
    } 
} 
2

你可以測試是否有確切一些價值觀,通過例如:

for(MyBoolean b : MyBoolean.values()) { 
    switch(b) { 
    case TRUE: 
     break; 
    case FALSE: 
     break; 
    default: 
     throw new IllegalArgumentException(b.toString()); 
} 

for(String s : new String[]{"TRUE", "FALSE" }) { 
    MyBoolean.valueOf(s); 
} 

如果有人刪除或添加值,一些測試的失敗。