使用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 >
</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 () {
Person person = new Person ();
when(person).setAge(-1 );
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 () {
Person person = new Person ();
when(person).setAge(-1 );
assertThat(caughtException(), allOf(
instanceOf(IllegalArgumentException.class)
, hasMessage("age is invalid" )
,hasNoCause()));
}
第一种最土鳖,第二种最简洁,第四种最靠谱。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!