最近在做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. excel 经验总结

    1.2007版excel表格中怎么将使用字母+数字下拉排序 比如:A201110300001怎么在excel表格中往下拉的时候变成A201110300002.A201110300003…… 方法: 因 ...

  2. mybatis系列-12-多对多查询

    12.1     需求 查询用户及用户购买商品信息. 12.2     sql语句 查询主表是:用户表 关联表:由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关联表: orders.or ...

  3. 【成都GamEver游戏公司诚邀服务器伙伴】【7~15k一年4次项目奖金】

    关于我们 我们厌倦了朝九晚五,一眼看到头的人生我们厌倦了耗费自己青春做的都是没有感情的项目平均从业经验5年以上行业顶尖美术和金牌制作人,资深欧美制作经验立志做中国的suppercell,公司小而美 我 ...

  4. ***JAVA多线程的应用场景和应用目的举例

    多线程使用的主要目的在于: 1.吞吐量:你做WEB,容器帮你做了多线程,但是他只能帮你做请求层面的.简单的说,可能就是一个请求一个线程.或多个请求一个线程.如果是单线程,那同时只能处理一个用户的请求. ...

  5. [apkAnalyzer] 查看APK包名

    最近项目中要用到APK的包名,必应到apkAnalyzer这个软件可以用,下载解压后,看到这么些jar,bat文件不知道怎么用. 参考了这篇文章,看的也不甚明白,最后还是试出来了,这里记录一下. 首先 ...

  6. Android“This Handler class should be static or leaks might occur”警告的处理方法

    此文属于转载! 最近用到handle在线程中改变UI,会跟给出“This Handler class should be static or leaks might occur”的警告,网上看了很多解 ...

  7. Cocos2dx游戏源码合集(BY懒骨头+持续更新+2014.02.21)

    转自:http://blog.csdn.net/iamlazybone/article/details/19612941 声明: <萝莉快跑><喵汪大战>两个demo的原作者b ...

  8. work_6

    这次的作业是阅读C++11的新特性并提出问题,作为一个大部分代码都是用C++的基本语法并没有特别关注C++一代又一代新特性的学生来说,首先我阅读了一些关于新特性的文章.为了更快的理解,我首先选择了阅读 ...

  9. Web开发人员需知的Web缓存知识

    最近的译文距今已有4年之久,原文有一定的更新.今天踩着前辈们的肩膀,再次把这篇文章翻译整理下.一来让自己对web缓存的理解更深刻些,二来让大家注意力稍稍转移下,不要整天HTML5, 面试题啊叨啊叨的~ ...

  10. CF#190DIV.1

    /* CF#190DIV.1-C 题意:给你n个结点的树,给这些结点标记字母AB..Z,对于标记相同的结点路径上 的结点的标记必须有一个是大于该标记的:问是否可以标记(A是最大标记) 分析:整天思路就 ...