学习Java的同学注意了!!!
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:589809992 我们一起学Java!
使用JUnit来测试Java代码中的异常有很多种方式,你知道几种?
给定这样一个class。
Person.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 | 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 方式
1
2
3
4
5
6
7
8
9
10
11 | @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来检查异常。
1
2
3
4
5
6 | @Test(expected = IllegalArgumentException.class) public void shouldGetExceptionWhenAgeLessThan0() { Person person = new Person(); person.setAge(-1); }
|
这种方式看起来要简洁多了,但是无法检查异常中的消息。
ExpectedException rule
JUnit7以后提供了一个叫做ExpectedException
的Rule来实现对异常的测试。
1
2
3
4
5
6
7
8
9
10
11
12 | @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
1
2
3
4
5
6 | <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> |
然后这样书写测试。
1
2
3
4
5
6
7
8 | @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库。
1
2
3
4
5 | <dependency> <groupId>org.easytesting</groupId> <artifactId>fest-assert-core</artifactId> <version>2.0M10</version> </dependency> |
然后可以书写BDD风格的测试。
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | @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。
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | @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())); }
|
第一种最土鳖,第二种最简洁,第四种最靠谱。
学习Java的同学注意了!!!
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:589809992 我们一起学Java!