博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用JUnit测试预期异常
阅读量:5161 次
发布时间:2019-06-13

本文共 2176 字,大约阅读时间需要 7 分钟。

开发人员常常使用单元测试来验证的一段儿代码的操作,很多时候单元测试可以检查抛出预期异常( expected exceptions)的代码。在Java语言中,JUnit是一套标准的单元测试方案,它提供了很多验证抛出的异常的机制。本文就探讨一下他们的优点。

我们拿下面的代码作为例子,写一个,确保canVote() 方法返回true或者false, 同时你也能写一个测试用来验证这个方法抛出的IllegalArgumentException异常。

 

(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异常。

@Rulepublic ExpectedException thrown= ExpectedException.none();

然后你可以使用更加简单的方式验证预期的异常。

@Testpublic void canVote_throws_IllegalArgumentException_for_zero_age() {    Student student = new Student();    thrown.expect(NullPointerException.class);    student.canVote(0);}

或者可以设置预期异常的属性信息。

@Testpublic 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();

它就像不需要的噪音一样,如果这样就很好了

或者:

 

或者至少可以将异常和信息当做参数传进去

 

thrown.expect(IllegalArgumentException.class, “age should be +ve”);

3.Try/catch with assert/fail

在JUnit4之前的版本中,使用try/catch语句块检查异常

@Testpublic 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()方法,如果预期异常没有抛出就会导致信息的误报。我曾经就犯过这样的错误。

总之,这三种方法都可以测试预期抛出的异常,各有优缺点。对于我个人而言,我会选择第二种方法,因为它可以非常精确、高效的测试异常信息。

翻译自:

转载于:https://www.cnblogs.com/xiadongqing/p/6970824.html

你可能感兴趣的文章
企业级编号
查看>>
Python面向对象
查看>>
高校成绩管理数据库系统的设计与实现 - 实验报告
查看>>
PM(Project Manager):系列博客
查看>>
spring事务之——spring配置事务的五种方式
查看>>
delphi数组之菜鸟篇
查看>>
node
查看>>
day01 Java基础
查看>>
Web开发应该注意的问题
查看>>
异常处理
查看>>
SSH2中实例化不了Action的一个原因
查看>>
EF,MVC相关项目请参见→
查看>>
HDFS常用命令
查看>>
图像处理与分析导论
查看>>
浅谈压缩感知(二十二):压缩感知重构算法之正则化正交匹配追踪(ROMP)
查看>>
二叉搜索树的后序遍历序列
查看>>
苹果向求职者抛出的8大难题
查看>>
杂项-数学软件:Mathematica
查看>>
第3章 深入理解init
查看>>
if判断IE浏览器的类型
查看>>