使用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中测试异常的多种方式的更多相关文章

  1. 夯实Java基础系列10:深入理解Java中的异常体系

    目录 为什么要使用异常 异常基本定义 异常体系 初识异常 异常和错误 异常的处理方式 "不负责任"的throws 纠结的finally throw : JRE也使用的关键字 异常调 ...

  2. 【Java心得总结二】浅谈Java中的异常

    作为一个面向对象编程的程序员对于 下面的一句一定非常熟悉: try { // 代码块 } catch(Exception e) { // 异常处理 } finally { // 清理工作 } 就是面向 ...

  3. Java中的异常-Throwable-Error-Exception-RuntimeExcetpion-throw-throws-try catch

    今天在做一个将String转换为Integer的功能时,发现Integer.parseInte()会抛出异常NumberFormatException. 函数Integer.parseInt(Stri ...

  4. java 获取classpath下文件多种方式

    java 获取classpath下文件多种方式 一:properties下配置 在resources下定义server.properties register.jks.path=classpath\: ...

  5. Java中反射的三种常用方式

    Java中反射的三种常用方式 package com.xiaohao.test; public class Test{ public static void main(String[] args) t ...

  6. Java中的异常详解

    一.异常定义 阻止当前方法或作用域继续执行的问题,称为异常 二.异常分析      所有不正常类都继承Throwable类,这个类主要有两个子类Error类和Exception类.Error指系统错误 ...

  7. Java中的异常和处理详解

    简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常.异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用C语言风格:用函数返回值作为执行状态?. ...

  8. Java中的异常简介

    Java中异常的分类 Java中的异常机制是针对正常运行程序的一个必要补充,一般来说没有加入异常机制,程序也能正常运营,但是,由于入参.程序逻辑的严谨度,总会有期望之外的结果生成,因此加入异常机制的补 ...

  9. Java中创建对象的五种方式

    我们总是讨论没有对象就去new一个对象,创建对象的方式在我这里变成了根深蒂固的new方式创建,但是其实创建对象的方式还是有很多种的,不单单有new方式创建对象,还有使用反射机制创建对象,使用clone ...

随机推荐

  1. 第一节(配置springmvc环境)学习尚硅谷-springmvc视频教程

    之前,一直从事C#开发.后来,公司调整后领导决定使用java开发,因此需要收集相关学习资料.该视频教程比较入门,也适合自己,于是边看边写的同时再总结一下便于自己牢记,遇到分歧不对之处望指正. 开发环境 ...

  2. OD使用教程3

    reverseMe爆破: 跳转指令 让跳转已实现,把z的1改成0 按F8走,继续把z的1改成0,实现跳转 根据跳转指令,改变s或o,使跳转不实现 指令如上使跳转不实现 继续按f8往下走然后成功  

  3. Unity将来时:IL2CPP是什么?

    作者:小玉链接:https://zhuanlan.zhihu.com/p/19972689来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. Unity3D 想必大家都不陌 ...

  4. BZOJ4350: 括号序列再战猪猪侠

    Description 括号序列与猪猪侠又大战了起来. 众所周知,括号序列是一个只有(和)组成的序列,我们称一个括号 序列S合法,当且仅当: 1.( )是一个合法的括号序列. 2.若A是合法的括号序列 ...

  5. yii安装 /You don't have permission to access on this server

    在安装yii的时候 ,当打开了init.bat进行配置的时候小黑本弹出了个小黑框立刻就关闭了,  进入cmd模式再打开init.bat就出现了"You don't have permissi ...

  6. eclipse 搭建Swt 环境

    我本是想用java开发一个记事本,开发记事本使用到SWT插件,我从网上找了许多的资料去集成插件,创建我的第一个SWT项目,以下是我搭建SWT环境的过程. 一.查看当前使用的exlipse 版本型号 在 ...

  7. STM32之PWM波形输出配置总结

    一.   TIMER分类: STM32中一共有11个定时器,其中TIM6.TIM7是基本定时器:TIM2.TIM3.TIM4.TIM5是通用定时器:TIM1和TIM8是高级定时器,以及2个看门狗定时器 ...

  8. oracle DBMS_LOCK.SLEEP()的使用

    create or replace procedure times isii positive:=1;beginloop dbms_lock.sleep(1);dbms_output.put_line ...

  9. 丙申年把真假美猴王囚禁在容器中跑 ASP.NET Core 1.0

    var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

  10. [LeetCode]413 Arithmetic Slices

    A sequence of number is called arithmetic if it consists of at least three elements and if the diffe ...