最近在做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. java web 学习一

    一.基本概念 1.1.WEB开发的相关知识 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. Internet上供外界访问的Web资源分为: 静态web资源( ...

  2. NiuTrans 日记 1

    这些天把东北大学自然语言实验室的NiuTrans 系统搭建并按照例子将短语系统运行了一遍,写这个日记主要是为了以后能提醒自己在这其中遇到的问题. 环境:短语系统我是windows和linux都运行了, ...

  3. 【九度OJ】题目1078-二叉树遍历

    题目 这道题和后面的两道题,题目1201和题目1009,主要内容是对递归的实现,在逻辑上,递归是容易理解的,这种实现方式和我们思考的方式是相吻合的.但是在转换为计算机语言时,要明确告知计算机应该从哪里 ...

  4. Tkinter教程之Canvas篇(2)

    本文转载自:http://blog.csdn.net/jcodeer/article/details/1811888 '''Tkinter教程之Canvas篇(2)''''''9.创建item的tag ...

  5. [Hive - LanguageManual] DML: Load, Insert, Update, Delete

    LanguageManual DML Hive Data Manipulation Language Hive Data Manipulation Language Loading files int ...

  6. Spark系列(十)TaskSchedule工作原理

    工作原理图 源码分析: 1.) 25              launchedTask = true 26            } 27          } catch { 28         ...

  7. 【Hadoop代码笔记】Hadoop作业提交之Child启动map任务

    一.概要描述 在上篇博文描述了TaskTracker启动一个独立的java进程来执行Map或Reduce任务.在本篇和下篇博文中我们会关注启动的那个入口是org.apache.hadoop.mapre ...

  8. grep in linux

    1.作用linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来.grep全称是Global Regular Expression Print,表示全局正 ...

  9. 删除ArrayList中的元素

    菜鸡重大发现:删除arraylist时,每删除一个元素后面的元素会自动填充 public static void main(String[] args) { List<String> li ...

  10. 惊艳的随机化方法 -World Search (homework-04)

    homeword04-word search 0. 摘要 本次作业,要求完成一个word search的程序,具体要求是: 输入:一个包含20-60个单词的文件,各单词不大于20个字母,无空格. 输出 ...