2011-12-20 45 views
4

我正在測試Xalan使用的WeekConverter並想知道我的測試究竟在做什麼。 :dJUnit測試異常期望(多重聲明)

具有以下測試方法:

@Test(expected = IllegalArgumentException.class) 
    public void testConvertTwoDigitYearWithWrongInput() { 
    WeekConverter weekConverter = new WeekConverter(WeekConverter.Strategy.TWO_DIGIT_YEAR); 

    //wrong or empty inputs 
    assertEquals("0", weekConverter.convert("")); 
    assertEquals("0", weekConverter.convert("abcdefgh")); 
} 

將這個測試期望對所有異常斷言,或者只對第一個斷言?如果只有第一個,這意味着我必須爲每個斷言創建一個測試方法,但我期望在這兩種情況下都有相同的異常。有人可以在這裏確認我的例子嗎?

我也有一個測試null,這會產生一個空指針異常。軟驗證是以下情況:

if (inputDate == null) { 
    do something and throw NullPointerexception 
} else if (inputDate.isEmpty()) { 
    do something and throw IllegalArgumentException, since inputDate is not really null 
} else if (inputDate.matches(regex)) { 
    go futher and convert 
} else { 
    do something and throw IllegalArgumentException, since inputDate does not match regex 
} 

因此所述一個測試方法期待拋出:IllegalArgumentException具有兩個斷言。但很顯然,我需要兩種不同的測試方法,不僅要尊重JUnit的功能,還要期待兩種不同的狀態。

+0

既然你期待一個例外,你並不需要斷言等於 - 所有你需要的是轉換的呼叫。 – avandeursen 2011-12-26 21:41:34

回答

3

您可以將您的方法分解爲多種方法,但是如果您有很多輸入樣本,將會很不方便。

您可以用下面的辦法來代替:

@Test 
public void testConvertTwoDigitYearWithWrongInput() { 
    WeekConverter weekConverter = new WeekConverter(WeekConverter.Strategy.TWO_DIGIT_YEAR); 

    assertFailsToConvert(weekConverter, ""); 
    assertFailsToConvert(weekConverter, "abcdefgh"); 
} 

private void assertFailsToConvert(WeekConverter weekConverter, String input) { 
    try { 
     weekConverter.convert(input); 
     fail("Should not convert [" + input + "]"); 
    } catch (IllegalArgumentException ex) {} 
} 
+0

這樣做的問題在於,如果沒有查看測試,測試不再是自我記錄,並且不能以沒有AST和猜測的人類可讀形式記錄。保持它們分開允許更好的信息生成。 – 2011-12-20 17:02:22

+0

excactly(評論) – 2011-12-20 17:07:32

+1

但是,針對不同輸入樣本進行大量單獨測試會妨礙可讀性和可維護性,因此您應該決定哪些對您更重要。 – axtavt 2011-12-20 17:10:33

1

您應該提供多種測試方法,因爲他們正在測試不同的東西。

第一次轉換器得到非法參數時將引發異常。

您還應該測試空輸入,以便記錄行爲。

+0

這是一個很好的觀點......特別是當拋出相同的異常但來自不同的狀態。 – 2011-12-20 16:56:06

1

測試只是期待IllegalArgumentException被拋出,無論從哪裏或爲什麼拋出。

我建議你把它分成兩個測試。

1

你可以把轉換夾具創建一個單獨的@Before設置方法,然後你可以有(三級)測試用例來對付null,「」和「abcdef」。

如果有更多的案例需要測試, 在JUnit中的一個整潔的方法是使用@Parameters註釋和相應的跑步者。

你的測試課只處理不正確的兩位數的年份。其構造函數將使用String類型的inputDate進行參數化。

產生@Parameters的靜態方法將返回包含""abcdefg(以及其他有趣的情況)的集合。

單個測試用例預期爲IllegalArgumentException

@RunWith(Parameterized.class) 
public class IncorrectTwoDigitYears { 
    String inputDate; 

    public IncorrectTwoDigitYears(String inputDate) { 
     this.inputDate = inputDate; 
    } 

    @Test(expected = IllegalArgumentException.class) 
    public void testFormat() { 
     (new WeekConverter(WeekConverter.Strategy.TWO_DIGIT_YEAR)) 
      .convert(inputDate); 
    } 

    @Parameters 
    public static Collection<Object[]> data() { 
     Object[][] data = new Object[][] { 
      { "" }, { "abcdef" }, { "0" }, { "000" }, { "##" } }; 
     return Arrays.asList(data); 
    } 
} 

如果您有兩個以上的案例需要測試,回報將會更高。

1

嘗試catch-exception

@Test 
public void testConvertTwoDigitYearWithWrongInput() { 

    WeekConverter weekConverter = ... 

    // wrong or empty inputs 
    verifyException(weekConverter, IllegalArgumentException.class) 
     .convert(""); 
    verifyException(weekConverter, IllegalArgumentException.class) 
     .convert("abcdefgh"); 
}