最近在做TWU关于TDD的作业,对JUnit中测试异常抛出的方法进行了一些学习和思考。

在进行单元测试的时候有的时候需要测试某一方法是否抛出了正确的异常。例如,我有一个方法,里面对一个List进行读取操作,可能会抛出IndexOutOfBoundsException,我希望在单元测试中通过测试保证该方法会正确的抛出正确类型的异常。总结起来这样的测试异常是否被正确抛出的方法有三种:

1. try…fail...catch…

@Test
public voidtestExceptionMessage() {
try {
new ArrayList<Object>().get(0);
fail("Expected an IndexOutOfBoundsException to be thrown");
} catch (IndexOutOfBoundsException anIndexOutOfBoundsException) {
assertThat(anIndexOutOfBoundsException.getMessage(), is("Index: 0, Size: 0"));
}
}

这种写法看上去和实现类的写法很相似,当没有异常被抛出的时候fail方法会被调用,输出测试失败的信息。

2.@Test(expected=xxx)

@Test(expected= IndexOutOfBoundsException.class)
public void empty() {
new ArrayList<Object>().get(0);
}

这种写法看上去简单了一些,但是它有一个潜在的问题:当被标记的这个测试方法中的任何一个操作抛出了相应的异常时,这个测试就会通过。这就意味着有可能抛出异常的地方并不是我们期望的那个操作。虽然这种情况可以在写test case的时候人为的避免,但是还是有更好的方法来测试异常抛出。

3.ExpectedException Rule

@Rule
public ExpectedException thrown = ExpectedException.none(); @Test
public void shouldTestExceptionMessage() throws IndexOutOfBoundsException {
List<Object> list = new ArrayList<Object>();
thrown.expect(IndexOutOfBoundsException.class);
thrown.expectMessage("Index: 0, Size: 0");
list.get(0); // execution will never get past this line
}

这种方法除了可以指定期望抛出的异常类型之外还可以指定在抛出异常时希望同时给出的异常信息。它需要在测试之前使用Rule标记来指定一个ExpectedException,并在测试相应操作之前指定期望的Exception类型(如IndexOutOfBoundException.class)

这三种方法都可以做到测试相应的操作是否抛出了期望的异常,但是哪种方法更好更适合使用呢?我的总结是:

@Test(expected=xxx)  >  根本不测异常是否正确抛出
ExpectedException  >  @Test(expected=xxx)

try…fail…catch  >  ExpectedException

我之所以认为try…fail…catch方法比ExpectedException好是因为:

1. try…fail…catch更符合一般的test function的风格,先进行某项操作,在对结果进行assert。而ExpectedException的顺序确实先指明期待的结果再进行相应的操作。

2. 虽然TDD的最佳实践是每个test function只有一个assert,但是还是在有些情况下会在同一个test function里使用多个assert来对不同的方面进行测试。但是使用ExpectedException进行异常测试后,当前的test function就结束了,如果在expect的相应操作之后还有assert的话会被自动跳过,而try…fail…catch则不会跳出当前test function, 其后面的assert依然会被顺序执行。

3. ExpectedException是JUnit提供的,因此在使用别的测试框架时这样的测试方法无效。而try/catch有更多的测试框架支持(fail也是JUnit提供的。使用别的测试框架的时候不能使用fail来给出测试失败的信息)

JUnit中测试异常抛出的方法的更多相关文章

  1. 在java中,异常抛出点后程序的执行情况

    1.在throw语句,即自定义的抛出异常语句后面的代码并不会执行,会提示错误,编译器并不可以正常编译. 2.若在一个条件语句中抛出一个异常,程序可以编译,但不会运行(dead code). 3.若在一 ...

  2. Swift 中异常抛出和四种异常处理

    在Swift中你可以像其他语言一样抛出异常处理异常,今天我们就详细地说说Swift中的异常抛出和处理. 在一开始我们要定义错误或者说是异常,Swift中的一些简单异常可以使用枚举定义,注意这个枚举要继 ...

  3. python3中try异常调试 raise 异常抛出

    一.什么是异常? 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行. 一般情况下,在Python无法正常处理程序时就会发生一个异常. 异常是Python对象,表示一个错误. 当Py ...

  4. python3 中的try 异常调试与 raise 异常抛出

    一.什么是异常? 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行. 一般情况下,在Python无法正常处理程序时就会发生一个异常. 异常是Python对象,表示一个错误. 当Py ...

  5. 编写Java程序,模拟五子棋博弈过程中的异常声明和异常抛出

    返回本章节 返回作业目录 需求说明: 模拟五子棋博弈过程中的异常声明和异常抛出,判断用户所下棋子的位置,是否超越了棋盘的边界. 棋盘的横坐标的范围为0-9,纵坐标范围为0-14,如果用户所放棋子的坐标 ...

  6. (转)spring异常抛出触发事务回滚策略

    背景:在面试时候问到事务方法在调用过程中出现异常,是否会传递的问题,平时接触的比较少,有些懵逼. spring异常抛出触发事务回滚策略 Spring.EJB的声明式事务默认情况下都是在抛出unchec ...

  7. 窥探Swift编程之错误处理与异常抛出

    在Swift 2.0版本中,Swift语言对其错误处理进行了新的设计,当然了,重新设计后的结果使得该错误处理系统用起来更爽.今天博客的主题就是系统的搞一下Swift中的错误处理,以及看一下Swift中 ...

  8. java的异常抛出和String类常用方法

    一.异常抛出 异常是程序的异种非错误的意外情况,分为运行期异常(RuntimeException)和编译期异常(CheckedExcption) 处理异常可以用try——catch或自定义 impor ...

  9. PLSQL_Oracle Exception异常分类、异常抛出、异常处理、异常传播(概念)

    2014-06-03 Created By BaoXinjian

随机推荐

  1. 仿it快播顶部button点击背景滑动切换的效果

    最近在it快播中看见它顶部的几个button可以点击后 背景会滑动到相应的button后面 就得很好看 就想办法实现了那效果 思路 大概就是通过view的叠加 把3个button通过RelativeL ...

  2. java 读取TXT文件的方法

    java读取txt文件内容.可以作如下理解: 首先获得一个文件句柄.File file = new File(); file即为文件句柄.两人之间连通电话网络了.接下来可以开始打电话了. 通过这条线路 ...

  3. 七中滤波方法测试matlab实现

    http://blog.163.com/xiaheng0804@126/blog/static/1205282120132129471816/ 创建两个混合信号,便于更好测试滤波器效果.同时用七中滤波 ...

  4. Chapter 2 Build Caffe

    Caffe for windows 的build药按照一定的顺序进行. ============================================================ 先以b ...

  5. Codevs No.1163 访问艺术馆

    2016-05-31 20:48:47 题目链接: 访问艺术馆 (Codevs No.1163) 题目大意: 一个贼要在一个二叉树结构的艺术馆中偷画,画都处于叶子节点处,偷画和经过走廊都需要时间,求在 ...

  6. java 最佳且开源的反编译工具

    1.jad:2.jode 很多gui的反编译工具(decafe,DJ,cavaJ)差不多都是基于jad和jode的.

  7. ES6学习(1)——如何通过babel将ES6转化成ES5

    使用babel编译ES6 babel是一个工具,可以通过多个平台,让js文件从ES6转化成ES5,从而支持一些浏览器并未支持的语法. Insall babel $ sudo npm install b ...

  8. codeforces 630C Lucky Numbers

    C. Lucky Numbers time limit per test 0.5 seconds memory limit per test 64 megabytes input standard i ...

  9. 详解Java解析XML的四种方法

    XML现在已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便.对于XML本身的语法知识与技术细节,需要阅读相关的技术文献,这里面包括的内容有DOM ...

  10. HDU 4052 Adding New Machine (线段树+离散化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4052 初始给你w*h的矩阵,给你n个矩形(互不相交),按这些矩形尺寸把初始的矩形扣掉,形成一个新的'矩 ...