簡體   English   中英

了解JUnit 5中的異常測試

[英]Understanding Exception tests in JUnit 5

我已經離開Java一段時間了,JUnit 5同時出現了。 我正在嘗試將一些現有的JUnit 4測試重寫為JUnit 5,但我正在努力解決如何處理拋出異常的方法。 例如,我有一個名為LocalizationUtils的類(不要與API中找到的任何其他類混淆),它有一個名為getResources()的方法,它需要一個非空的基本名稱作為輸入並返回如果可以找到相應的資源包。 如果基本名稱為null,則拋出NullPointerException;如果無法找到資源束,則拋出MissingResourceException。 這是代碼:

    static public ResourceBundle getResources(String baseName) throws NullPointerException, MissingResourceException {

    if (baseName == null) {
        final String msg = "The base name cannot be null.";
        NullPointerException npExcp = new NullPointerException(msg); 
        Logger logger = Logger.getLogger(CLASS_NAME);
        logger.log(Level.SEVERE, msg, npExcp);
        throw npExcp;
        }

    /* Get the resource bundle for the current locale. */
    try {
        return(ResourceBundle.getBundle(baseName));
        } 
    catch (MissingResourceException mrExcp) {
        String msg = "Unable to find resources for base name " + baseName + "."; 
        Logger logger = Logger.getLogger(CLASS_NAME);
        logger.log(Level.SEVERE, msg, mrExcp); 
        throw mrExcp;
        }

}   

JUnit 5的手冊給出了處理異常的示例:

@Test
void exceptionTesting() {
    Throwable exception = assertThrows(IllegalArgumentException.class, () -> {
        throw new IllegalArgumentException("a message");
    });
    assertEquals("a message", exception.getMessage());
}

這個例子對我來說毫無意義。 它似乎是憑空消息創造了一條“消息”的例外。 我沒有看到它實際上正在執行任何類或方法。 對於這應該如何工作沒有真正的解釋,所以可能/可能這只是我的誤解。

為了編寫一個實際執行我的代碼並強制發生錯誤的測試,我編寫了這個JUnit 5測試:

@Test
void testGetResourcesString() {

    //Normal cases

    //Exception - input parameter is null
    /* Verify that the expected type of exception was thrown. */
    Throwable npExcp = assertThrows(NullPointerException.class, () -> {
        LocalizationUtils.getResources(null);
    });   
    /* Verify that the exact right error message was generated. */   
    assertEquals("The base name cannot be null.", npExcp.getMessage()); 


    //Exception - all input is non-null but resource bundle not found
    /* Verify that the expected type of exception was thrown. */
    Throwable mrExcp = assertThrows(MissingResourceException.class, () -> {
        LocalizationUtils.getResources("foo");
    });   
    /* Verify that the exact right error message was generated. */
    assertEquals("Can't find bundle for base name foo, locale en_CA", mrExcp.getMessage());     
}

此測試中的所有內容都按照我的預期工作,它似乎比手冊中的示例更合乎邏輯,因為它實際上執行了一個類和方法來引發異常。 我還想確保生成了正確的消息,因為很容易想象一個帶有多個輸入參數的方法,而不是只有一個任何參數為null的方法應該拋出一個帶有唯一消息的異常。 簡單地確定拋出了正確的異常對我來說似乎不夠:我覺得我想確保創建了正確的消息,以便我知道代碼正在對幾個正確的null參數做出反應。

我不願意相信手冊錯了; 我想一個由幾位經驗豐富的開發人員組成的團隊編寫並非常小心。 任何擁有比我更多JUnit 5知識的人 - 必須是所有使用過JUnit 5的人 - 確認手冊中的示例是正確的,如果是,那么當沒有類或方法名稱時它應該如何工作提供?

該示例確實稱為“方法”。 lambda表達式() -> {...}定義了一個匿名方法 它包含一個語句: throw new IllegalArgumentException

請參閱java語言規范

() -> {}                // No parameters; result is void
() -> 42                // No parameters, expression body
() -> null              // No parameters, expression body
() -> { return 42; }    // No parameters, block body with return
() -> { System.gc(); }  // No parameters, void block body
(int x) -> x+1              // Single declared-type parameter
(int x) -> { return x+1; }  // Single declared-type parameter
(x) -> x+1                  // Single inferred-type parameter
 x  -> x+1                  // Parens optional for single inferred-type case

所以這個例子有一個方法,它只是拋出一個異常。

() -> { throw new IllegalArgumentException("a message"); }

您的代碼中,您實際上是在定義一個沒有參數的方法,使用一個參數調用您的方法。

() -> { LocalizationUtils.getResources(null); } 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM