junit 使用JUnit測試預期異常
開發人員常常使用單元測試來驗證的一段兒程式碼的操作,很多時候單元測試可以檢查丟擲預期異常(expected exceptions)的程式碼。在Java語言中,JUnit是一套標準的單元測試方案,它提供了很多驗證丟擲的異常的機制。本文就探討一下他們的優點。
我們拿下面的程式碼作為例子,寫一個測試,確保canVote() 方法返回true或者false, 同時你也能寫一個測試用來驗證這個方法丟擲的IllegalArgumentException異常。
public class Student {
public boolean canVote(int age) {
if (i<=0) throw new IllegalArgumentException("age should be +ve");
if (i<18) return false;
else return true;
}
}
(Guava類庫中提供了一個作引數檢查的工具類–Preconditions類,也許這種方法能夠更好的檢查這樣的引數,不過這個例子也能夠檢查)。
檢查丟擲的異常有三種方式,它們各自都有優缺點:
1.@Test(expected…)
@Test註解有一個可選的引數,”expected”允許你設定一個Throwable的子類。如果你想要驗證上面的canVote()方法丟擲預期的異常,我們可以這樣寫:
@Test(expected = IllegalArgumentException.class)
public void canVote_throws_IllegalArgumentException_for_zero_age() {
Student student = new Student();
student.canVote(0);
}
簡單明瞭,這個測試有一點誤差,因為異常會在方法的某個位置被丟擲,但不一定在特定的某行。
2.ExpectedException
如果要使用JUnit框架中的ExpectedException類,需要宣告ExpectedException異常。
@Rule
public ExpectedException thrown= ExpectedException.none();
然後你可以使用更加簡單的方式驗證預期的異常。
@Test
public void canVote_throws_IllegalArgumentException_for_zero_age() {
Student student = new Student();
thrown.expect(IllegalArgumentException.class);
student.canVote(0);
}
或者可以設定預期異常的屬性資訊。
@Test
public void canVote_throws_IllegalArgumentException_for_zero_age() {
Student student = new Student();
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("age should be +ve");
student.canVote(0);
}
除了可以設定異常的屬性資訊之外,這種方法還有一個優點,它可以更加精確的找到異常丟擲的位置。在上面的例子中,在建構函式中丟擲的未預期的(unexpected) IllegalArgumentException 異常將會引起測試失敗,我們希望它在canVote()方法中丟擲。
從另一個方面來說,如果不需要宣告就更好了
@Rule
public ExpectedException thrown= ExpectedException.none();
它就像不需要的噪音一樣,如果這樣就很好了
expect(RuntimeException.class)
或者:
expect(RuntimeException.class, “Expected exception message”)
或者至少可以將異常和資訊當做引數傳進去
thrown.expect(IllegalArgumentException.class, “age should be +ve”);
3.Try/catch with assert/fail
在JUnit4之前的版本中,使用try/catch語句塊檢查異常
@Test
public void canVote_throws_IllegalArgumentException_for_zero_age() {
Student student = new Student();
try {
student.canVote(0);
} catch (IllegalArgumentException ex) {
assertThat(ex.getMessage(), containsString("age should be +ve"));
}
fail("expected IllegalArgumentException for non +ve age");
}
儘管這種方式很老了,不過還是非常有效的。主要的缺點就是很容易忘記在catch語句塊之後需要寫fail()方法,如果預期異常沒有丟擲就會導致資訊的誤報。我曾經就犯過這樣的錯誤。
總之,這三種方法都可以測試預期丟擲的異常,各有優缺點。對於我個人而言,我會選擇第二種方法,因為它可以非常精確、高效的測試異常資訊。
轉載自:使用JUnit測試預期異常
相關文章
- Junit mockito 測試Controller層方法有Pageable異常MockitoController
- JUnit測試方法
- JUnit3.8的Junit單元測試.
- 【JUnit測試】總結
- JUnit單元測試
- Junit 單元測試.
- Junit 4 測試方法
- 使用JUnit進行單元測試
- 使用junit單元測試SpringMvcSpringMVC
- Junit 單元測試使用總結
- junit-單元測試
- Android的Junit測試Android
- JUnit 4 單元測試
- Myexclipse建立Junit測試
- JUnit測試單元框架框架
- springboot junit測試Spring Boot
- Junit單元測試—MavenMaven
- junit測試工具運用
- 安卓單元測試 (八):Junit Rule 的使用安卓
- Android單元測試(3):JUnit 的使用Android
- Java單元測試之junitJava
- Junit4單元測試
- Junit測試Android自動化測試Android
- JUnit5編寫基本測試
- 1.13-java單元測試junitJava
- junit執行多個測試類
- 實驗三junit單元測試
- Junit5系列-Junit5中DisabledCondition條件測試執行
- 在JUnit中使用@Rule測試檔案和目錄
- junit 測試中各種斷言用法
- eclipse maven打包 跳過junit測試EclipseMaven
- JF +Spring 4 +JUNIT4 測試?Spring
- 用Junit Framework編寫單元測試Framework
- spring1.2+hibernate3.0+junit3.8+jdk1.4的單元測試異常解決方法SpringJDK
- JUnit使用總結
- JUnit —— TestSuite 的使用UI
- JUnit使用經驗
- Java單元測試之JUnit 5快速上手Java