2013-03-12 59 views
3

我正在爲JUnit4項目進行場景測試。JUnit4預期異常

在其中一個測試中,我需要檢查預期的異常。使用JUnit4,我使用註釋來完成此操作。

@Test(expected=...) 

現在的問題是,在拋出異常的測試代碼的下面有我需要檢查哪些沒有得到excecuted其他一些註解。爲例進行了說明:

@Test(expected=NullPointerException.class) 
    public void nullPointerTest() { 
     Object o = null; 
     o.toString(); 
     assertTrue(false); 
    } 

該測試通過,因爲它得到的NullPointerException但有顯然與asserTrue(假)斷言錯誤,因此我希望它失敗。

解決此問題的最佳方法是什麼?對此的解決方案可能如下,但我不知道這是否是正確的方法。

@Test 
public void nullPointerTest2() { 
    boolean caught = false; 
    try{ 
     Object o = null; 
     o.toString(); 
    } 
    catch(NullPointerException e) 
    { 
     caught = true; 
    } 
    assertTrue(caught); 
    assertTrue(false); 
} 

第二個測試按預測失敗。

+0

你爲什麼要做'assertTrue(false)'?或者這是否代表您的一些真實測試代碼?這個「真實」的代碼是否依賴於引發'NullPointerException'的代碼? – rgettman 2013-03-12 00:19:59

+0

我不知道你爲什麼想要這樣做。它聞起來糟糕的測試設計。每個測試只應該測試一件事情。 – Aurand 2013-03-12 00:22:43

+1

我建議你把它分成兩個單獨的測試。 – 2013-03-12 00:24:13

回答

3

JUnit4的行爲如預期:拋出異常時,執行不會繼續。所以NullPointerException被拋出,測試方法退出,JUnit4將其標記爲傳遞,因爲你期望有一個異常。空解除引用後的代碼不存在。

如果你想要第二次測試的行爲,那麼你寫的是一個很好的解決方案。但這是一件奇怪的事情要。在我看來,你正在混淆兩個不同的測試。一個測試應該測試在特殊情況下拋出異常。第二個測試應該測試任何第二個斷言檢查。

+0

我不同意上面的例子是'怪異的'。考慮到在被測試類拋出異常的情況下,它可能還會在拋出異常之前執行其他可測試步驟(例如釋放資源,記錄錯誤,更新狀態等) – 2013-03-12 11:08:24

+0

是的,如果它是*事先*處理異常,那麼一切都會奏效。如果早期斷言失敗,測試將失敗。如果後面的異常沒有被拋出,那麼測試將失敗。有什麼奇怪的是期待一個測試拋出一個異常,然後在*之後*做任何事情。拋出的異常是函數的結束(否則它不會被拋出,它會被捕獲)。 – 2013-03-12 11:57:42

4

考慮:

@Test(expected=NullPointerException.class) 
public void nullPointerTest2() { 
    boolean caught = false; 
    try{ 
    Object o = null; 
    o.toString(); 
    } 
    catch(NullPointerException e) 
    { 
    // test other stuff here 
    throw e; 
    } 
} 

這允許額外的檢查,同時還充分利用JUnit的內置的異常檢查。

此外,我認爲在許多情況下使用@Rule ExpectedException是更好的選擇,即expected