JUnit中测试异常抛出的方法
最近在做TWU關于TDD的作業,對JUnit中測試異常拋出的方法進行了一些學習和思考。
在進行單元測試的時候有的時候需要測試某一方法是否拋出了正確的異常。例如,我有一個方法,里面對一個List進行讀取操作,可能會拋出IndexOutOfBoundsException,我希望在單元測試中通過測試保證該方法會正確的拋出正確類型的異常??偨Y起來這樣的測試異常是否被正確拋出
校驗方式有三種:
1. try…fail…catch…
@Test public voidtestExceptionMessage() {try {new ArrayList<Object>().get(0);fail("Expected an IndexOutOfBoundsException to be thrown");} catch (IndexOutOfBoundsException anIndexOutOfBoundsException) {assertThat(anIndexOutOfBoundsException.getMessage(), is("Index: 0, Size: 0"));} }這種寫法看上去和實現類的寫法很相似,當沒有異常被拋出的時候fail方法會被調用,輸出測試失敗的信息。
2.@Test(expected=xxx)
@Test(expected= IndexOutOfBoundsException.class) public void empty() { new ArrayList<Object>().get(0); }這種寫法看上去簡單了一些,但是它有一個潛在的問題:當被標記的這個測試方法中的任何一個操作拋出了相應的異常時,這個測試就會通過。這就意味著有可能拋出異常的地方并不是我們期望的那個操作。雖然這種情況可以在寫test case的時候人為的避免,但是還是有更好的方法來測試異常拋出。
3.ExpectedException Rule
@Rule public ExpectedException thrown = ExpectedException.none();@Test public void shouldTestExceptionMessage() throws IndexOutOfBoundsException {List<Object> list = new ArrayList<Object>();thrown.expect(IndexOutOfBoundsException.class);thrown.expectMessage("Index: 0, Size: 0");list.get(0); // execution will never get past this line }這種方法除了可以指定期望拋出的異常類型之外還可以指定在拋出異常時希望同時給出的異常信息。它需要在測試之前使用Rule標記來指定一個ExpectedException,并在測試相應操作之前指定期望的Exception類型(如IndexOutOfBoundException.class)
這三種方法都可以做到測試相應的操作是否拋出了期望的異常,但是哪種方法更好更適合使用呢?
我的總結是:
try…fail…catch > ExpectedException > @Test(expected=xxx)
我之所以認為try…fail…catch方法比ExpectedException好是因為:
try…fail…catch更符合一般的test function的風格,先進行某項操作,在對結果進行assert。而ExpectedException的順序確實先指明期待的結果再進行相應的操作。
雖然TDD的最佳實踐是每個test function只有一個assert,但是還是在有些情況下會在同一個test function里使用多個assert來對不同的方面進行測試。但是使用ExpectedException進行異常測試后,當前的test function就結束了,如果在expect的相應操作之后還有assert的話會被自動跳過,而try…fail…catch則不會跳出當前test function, 其后面的assert依然會被順序執行。
ExpectedException是JUnit提供的,因此在使用別的測試框架時這樣的測試方法無效。而try/catch有更多的測試框架支持(fail也是JUnit提供的。使用別的測試框架的時候不能使用fail來給出測試失敗的信息)
-----以下是我自己的看法:
try…fail…catch 這種寫法,比較容易忽略catch前面的fail(),且不容易檢查,
一般我們看到try…catch會認為是對拋出的異常做處理,但在這里是在驗證,閱讀代碼時不流暢,且容易讓其他人有誤解
個人比較喜歡ExpectedException的方式
但是在實際使用過程中,如果需要有其他的斷言或者mock的verify的判斷,使用 try…fail…catch的寫法可以比較好的覆蓋,否則后面的斷言和verify就無法執行了。
總結
以上是生活随笔為你收集整理的JUnit中测试异常抛出的方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《MySQL实战45讲》基础理论篇 1-
- 下一篇: ON DUPLICATE KEY UPD