使用JUnit來測試Java代碼中的異常
給定這樣一個class。
Person.java public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { if (age < 0 ) { throw new IllegalArgumentException("age is invalid"); } this.age = age; } } |
我們來測試setAge方法。
Try-catch 方式 @Test public void shouldGetExceptionWhenAgeLessThan0() { Person person = new Person(); try { person.setAge(-1); fail("should get IllegalArgumentException"); } catch (IllegalArgumentException ex) { assertThat(ex.getMessage(),containsString("age is invalid")); } } |
這是最容易想到的一種方式,但是太啰嗦。
JUnit annotation方式
JUnit中提供了一個expected的annotation來檢查異常。
@Test(expected = IllegalArgumentException.class) public void shouldGetExceptionWhenAgeLessThan0() { Person person = new Person(); person.setAge(-1); } |
這種方式看起來要簡潔多了,但是無法檢查異常中的消息。
ExpectedException rule
JUnit7以后提供了一個叫做ExpectedException的Rule來實現對異常的測試。
@Rule public ExpectedException exception = ExpectedException.none(); @Test public void shouldGetExceptionWhenAgeLessThan0() { Person person = new Person(); exception.expect(IllegalArgumentException.class); exception.expectMessage(containsString("age is invalid")); person.setAge(-1); } |
這種方式既可以檢查異常類型,也可以驗證異常中的消息。
使用catch-exception庫
有個catch-exception庫也可以實現對異常的測試。
首先引用該庫。
pom.xml
<dependency>
<groupId>com.googlecode.catch-exception</groupId>
<artifactId>catch-exception</artifactId>
<version>1.2.0</version>
<scope>test</scope> <!-- test scope to use it only in tests -->
</dependency>
然后這樣書寫測試。
@Test
public void shouldGetExceptionWhenAgeLessThan0() {
Person person = new Person();
catchException(person).setAge(-1);
assertThat(caughtException(),instanceOf(IllegalArgumentException.class));
assertThat(caughtException().getMessage(), containsString("age is invalid"));
}
這樣的好處是可以精準的驗證異常是被測方法拋出來的,而不是其它方法拋出來的。
catch-exception庫還提供了多種API來進行測試。
先加載fest-assertion庫。
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-assert-core</artifactId>
<version>2.0M10</version>
</dependency>
然后可以書寫BDD風格的測試。
@Test public void shouldGetExceptionWhenAgeLessThan0() { // given Person person = new Person(); // when when(person).setAge(-1); // then then(caughtException()) .isInstanceOf(IllegalArgumentException.class) .hasMessage("age is invalid") .hasNoCause(); } |
如果喜歡Hamcrest風格的驗證風格的話,catch-exception也提供了相應的Matcher API。
@Test public void shouldGetExceptionWhenAgeLessThan0() { // given Person person = new Person(); // when when(person).setAge(-1); // then assertThat(caughtException(), allOf( instanceOf(IllegalArgumentException.class) , hasMessage("age is invalid") ,hasNoCause())); } |
第一種最土鱉,第二種最簡潔,第四種最靠譜。
posted on 2014-07-10 19:26 順其自然EVO 閱讀(2542) 評論(0) 編輯 收藏 所屬分類: 測試學習專欄