2016-08-02 241 views
0

我創建了以下用於驗證羅馬數字轉換器的方法。 在JUnit中,測試通過但程序不會拋出任何異常。 我錯在哪裏?如何在Java中測試異常Junit

public void validateState(String number){ 
    if(!number.matches("^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$")) 
     throw new IllegalArgumentException("Invalid number"); 

    System.out.println("Invalid number"); 
} 

測試:

@Test(expected = IllegalArgumentException.class) 
public void test15() throws Exception { 
    new RomanNumber("").validateState("MMMMM"); 
} 

謝謝你的幫助。

+0

使用調試器找到它 – Jens

+0

這可能是在你的REGEX,檢查你的正則表達式的有效性 – Adelin

+0

小建議,一個字符串的變量名「數字」可能會導致潛在的混淆。 –

回答

4

如果測試通過,這意味着IllegalArgumentException引發您的方法。
否則,因爲在這裏你做一個斷言IllegalArgumentException拋出異常JUnit測試會失敗:

@Test(expected = IllegalArgumentException.class) 

刪除@Test(expected = IllegalArgumentException.class),你會看到測試失敗。


編輯回答您的評論: 爲什麼我沒有看到「無效號碼」的消息

你看到在輸出端(終端)堆棧跟蹤異常,如果異常是不被任何來電對象抓住。但正如我在我的評論中剛剛解釋的那樣,在您的情況中,您沒有看到異常,因爲它被JUnit(這是一個調用者對象)困住,因爲您在@Test註釋中使用了期望的屬性。當你運行你的方法時,JUnit跑步者攔截你拋出的IllegalArgumentException,因爲JUnit跑步者知道它必須檢查IllegalArgumentException被拋出。
只有當異常返回到調用堆棧的頂部時(這意味着執行代碼中沒有人發現異常),JVM纔會在輸出(此例中爲錯誤流)中寫入異常

+0

這是正常的,我沒有看到消息「無效號碼」? – InExperience

+1

@ user1526278如何看到在引發異常並終止執行的語句之後寫入的內容?你在那裏的系統應該是「有效的數字」 –

+0

@ user1526278這取決於你如何運行測試。如果您使用的是Eclipse,您應該通過在junit選項卡中單擊測試附近的綠色進度條來看到「無效數字」。當然,顯示的文本將是異常消息和堆棧跟蹤,而不是拋出異常之後的System.out.println。 – BackSlash

0

測試必須通過,你的邏輯是正確的。你的測試表明它期望拋出一個異常,它確實如此。 Junit捕獲異常,驗證它並使測試通過。

expected = IllegalArgumentException.class 

從您的@Test註釋中刪除此行,它將開始拋出異常。

+0

如果我刪除了@Test(expected = IllegalArgumentException.class),則測試會在其他測試用例上運行,編譯器會跳轉我感興趣的內容。 – InExperience

+0

不,不要刪除整個註釋,只是「expected = IllegalArgumentException.class」,如果你想看到錯誤! – Adelin

+0

但我的測試代碼是正確的? \t @Test(預期= IllegalArgumentException.class) \t公共無效test15()拋出異常{ \t \t新RomanNumber( 「」)(MMMMM 「)validateState。」; \t \t} – InExperience

0

你似乎會問,爲什麼

public void validateState(String number) { 
    if (!number.matches(...)) 
     throw new IllegalArgumentException("Invalid number"); 

    System.out.println("Invalid number"); 
} 

不拋出異常,並在同一時間打印錯誤消息。

原因是當引發異常時,它將傳播跳過語句,直到在封閉的try ... catch中捕獲異常。在這種情況下,println呼叫將被跳過。這是正常的Java行爲......

如果你想在異常被拋出的消息要打印,寫這樣的:

public void validateState(String number) { 
    if (!number.matches(...)) { 
     System.out.println("Invalid number"); 
     throw new IllegalArgumentException("Invalid number"); 
    } 
}