簡體   English   中英

JUnit4 @Test(expected = MyException.class)VS try / catch

[英]JUnit4 @Test(expected=MyException.class) VS try/catch

我正在考慮異常處理和單元測試最佳實踐,因為我們正在努力獲得一些代碼最佳實踐。

我們公司維基上發現的前一篇關於最佳實踐的文章指出“不要使用try / catch,而是使用Junit4 @Test(expect = MyException.class)”,沒有進一步的信息。 我不相信。

我們的許多自定義異常都有一個枚舉,以便識別失敗原因。 結果,我寧願看到如下的測試:

@Test
public void testDoSomethingFailsBecauseZzz() {
try{
   doSomething();
} catch(OurCustomException e){
   assertEquals("Omg it failed, but not like we planned", FailureEnum.ZZZ, e.getFailure());
}
}

比:

@Test(expected = OurCustomException.class)
public void testDoSomethingFailsBecauseZzz() {
   doSomething();
}

當doSomethig()看起來像:

public void doSomething throws OurCustomException {
  if(Aaa) {
     throw OurCustomException(FailureEnum.AAA);
  } 
  if(Zzz) {
     throw OurCustomException(FailureEnum.ZZZ);
  }
  // ...
}

在旁注中,我更確信在某些情況下@Test(expected = blabla.class)是最佳選擇(例如,當異常是精確的並且毫無疑問導致它的原因時)。

我在這里遺漏了什么,還是應該在必要時推動使用try / catch?

聽起來你的枚舉被用作異常層次結構的替代品? 也許如果你有一個異常層次結構, @Test(expected=XYZ.class)會變得更有用嗎?

  • 如果您只想檢查是否拋出了某種類型的異常,請使用注釋的expected屬性。
  • 如果要檢查拋出異常的屬性(例如消息或自定義成員值),請在測試中捕獲它並進行斷言。

在你的情況下,似乎你想要后者(斷言異常有一定的FailureEnum值); 使用try/catch沒有任何問題

你應該“不使用try / catch”(解釋為“從不”)的概括是無聊的。

傑夫是對的; 您的異常層次結構的組織是可疑的。 但是,你似乎認識到這一點。 :)

如果要檢查原始異常類型,則expected方法是合適的。 否則,如果你需要測試關於異常的一些東西(並且無論測試消息內容的enum怪異是否常見)你都可以嘗試catch,但這有點老了。 新的JUnit方法是使用MethodRule API中出現的一個( ExpectedException )是專門測試消息,但是您可以輕松查看代碼並調整該實現以檢查失敗enum

我在搜索如何處理異常時遇到了這個問題。

正如@Yishai所提到的,期望異常的首選方法是使用JUnit規則和ExpectedException

當使用@Test(expected=SomeException.class)如果在方法中的任何位置拋出異常,則測試方法將通過。

使用ExpectedException

@Test
public void testException()
{
    // If SomeException is thrown here, the test will fail.
    expectedException.expect(SomeException.class);
    // If SomeException is thrown here, the test will pass.
}

你也可以測試:

  • 預期的消息: ExpectedException.expectMessage() ;
  • 預期原因: expectedException.expectCause()

作為旁注:我不認為使用枚舉來處理異常消息/原因是一種很好的做法。 (如果我錯了,請糾正我。)

在您的特殊情況下,您希望測試(1)是否拋出預期的異常類型 ,以及(2)如果錯誤號是正確的,因為該方法可以使用不同的類型拋出相同的異常。

這需要檢查異常對象。 但是,您可以堅持建議驗證是否拋出了正確的異常:

@Test(expected = OurCustomException.class)
public void testDoSomethingFailsBecauseZzz() {
   try {
      doSomething();
   } catch (OurCustomException e) {
      if (e.getFailureEnum.equals(FailureEnum.ZZZ))  // use *your* method here
         throw e;

      fail("Catched OurCostomException with unexpected failure number: " 
        + e.getFailureEnum().getValue());  // again: your enum method here
   }
}

此模式將 吃掉意外的異常並使測試失敗。

編輯

改變它是因為我錯過了顯而易見的事情:我們可以使測試用例失敗並捕獲消息。 所以現在:如果拋出了帶有預期錯誤代碼的預期異常,則測試通過。 如果由於我們遇到意外錯誤而導致測試失敗,那么我們就可以讀取錯誤代碼。

我做了一個例外,因為我遇到了和你一樣的問題,Stph。 使用catch-exception,您的代碼可能如下所示:

@Test
public void testDoSomethingFailsBecauseZzz() {
   verifyException(myObj, OurCustomException.class).doSomething();
   assertEquals("Omg it failed, but not like we planned", FailureEnum.ZZZ,    
               ((OurCustomException)caughtException()).getFailure() ;
}

暫無
暫無

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

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