在JUnit中,有3种流行的方式来处理测试代码中的异常:

  • 尝试捕捉习语
  • 使用JUnit规则
  • 带注解

我们应该使用哪一个?何时使用?

尝试捕捉习语

这个习语是最受欢迎的习语之一,因为它已在JUnit 3中使用。

@Testpublic void throwsExceptionWhenNegativeNumbersAreGiven() {try {calculator.add("-1,-2,3");fail("Should throw an exception if one or more of given numbers are negative");} catch (Exception e) {assertThat(e).isInstanceOf(IllegalArgumentException.class).hasMessage("negatives not allowed: [-1, -2]");}}

上面的方法是一种常见的模式。 当没有引发异常并且在catch子句中验证了异常本身时,测试将失败(在上面的示例中,我使用了FEST Fluent断言),尽管它很好,但我更喜欢使用
ExpectedException规则。

使用JUnit规则

可以使用创建相同的示例
ExceptedException规则。 规则必须是标有@Rule批注的公共字段。 请注意,“抛出”规则可能会在许多测试中重复使用。

@Rulepublic ExpectedException thrown = ExpectedException.none();@Testpublic void throwsExceptionWhenNegativeNumbersAreGiven() {// arrangethrown.expect(IllegalArgumentException.class);thrown.expectMessage(equalTo("negatives not allowed: [-1, -2]"));// actcalculator.add("-1,-2,3");}

通常,我发现上面的代码更具可读性,因此我在项目中使用了这种方法。

当未引发异常时,您将收到以下消息: java.lang.AssertionError:预期引发的测试(java.lang.IllegalArgumentException的实例和带有消息“不允许负数的异常:[-1,-2]” ) 。 挺好的。

但并非所有例外情况我都可以通过上述方法进行检查。 有时我只需要检查抛出的异常的类型,然后使用@Test批注。

带注解

@Test (expected = IllegalArgumentException.class)public void throwsExceptionWhenNegativeNumbersAreGiven() {// actcalculator.add("-1,-2,3");}

当未引发异常时,您将收到以下消息: java.lang.AssertionError:预期的异常:java.lang.IllegalArgumentException

使用这种方法时,您需要小心。 有时很容易想到一般的ExceptionRuntimeException甚至Throwable 。 这被认为是一种不好的做法,因为您的代码可能会在实际未预期的地方引发异常,并且测试仍将通过!

综上所述,在我的代码中,我使用两种方法: JUnit规则注释 。 优点是:

  • 代码不引发异常时的错误消息会自动处理
  • 可读性得到改善
  • 创建的代码更少

您的喜好是什么?

我听说过处理异常的第四种方式(我的一位同事在阅读本文后提出了建议)–使用自定义注释。

乍一看,实际上该解决方案看起来不错,但是它需要您自己的JUnit运行程序,因此它有缺点:您不能将此批注与Mockito运行程序一起使用。

作为编码实践,我创建了这样的注释,所以也许有人觉得它有用

用法

@RunWith(ExpectsExceptionRunner.class)
public class StringCalculatorTest {@Test@ExpectsException(type = IllegalArgumentException.class, message = "negatives not allowed: [-1]")public void throwsExceptionWhenNegativeNumbersAreGiven() throws Exception {// actcalculator.add("-1,-2,3");}}

上面的测试将失败,并显示一条消息: java.lang.Exception:意外的异常消息,预期的

但是是

注释

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface ExpectsException {Class type();String message() default "";
}

带有复制和粘贴代码的跑步者

public class ExpectsExceptionRunner extends BlockJUnit4ClassRunner {public ExpectsExceptionRunner(Class klass) throws InitializationError {super(klass);}@Overrideprotected Statement possiblyExpectingExceptions(FrameworkMethod method, Object test, Statement next) {ExpectsException annotation = method.getAnnotation(ExpectsException.class);if (annotation == null) {return next;}return new ExpectExceptionWithMessage(next, annotation.type(), annotation.message());}class ExpectExceptionWithMessage extends Statement {private final Statement next;private final Class expected;private final String expectedMessage;public ExpectExceptionWithMessage(Statement next, Class expected, String expectedMessage) {this.next = next;this.expected = expected;this.expectedMessage = expectedMessage;}@Overridepublic void evaluate() throws Exception {boolean complete = false;try {next.evaluate();complete = true;} catch (AssumptionViolatedException e) {throw e;} catch (Throwable e) {if (!expected.isAssignableFrom(e.getClass())) {String message = "Unexpected exception, expected<"+ expected.getName() + "> but was <"+ e.getClass().getName() + ">";throw new Exception(message, e);}if (isNotNull(expectedMessage) && !expectedMessage.equals(e.getMessage())) {String message = "Unexpected exception message, expected<"+ expectedMessage + "> but was<"+ e.getMessage() + ">";throw new Exception(message, e);}}if (complete) {throw new AssertionError("Expected exception: "+ expected.getName());}}private boolean isNotNull(String s) {return s != null && !s.isEmpty();}}}
参考: 3种处理JUnit中异常的方法。 选择哪一个? 从我们的JCG合作伙伴 Rafal Borowiec在Codeleak.pl博客上获得。

翻译自: https://www.javacodegeeks.com/2013/11/3-ways-of-handling-exceptions-in-junit-which-one-to-choose.html

在JUnit中处理异常的3种方法。 选择哪一个?相关推荐

  1. junit 5测试异常处理_在JUnit中处理异常的3种方式。 选择哪一个?

    junit 5测试异常处理 在JUnit中,有3种流行的方式来处理测试代码中的异常: 试捕习语 使用JUnit规则 带注解 我们应该使用哪一个?何时使用? 试捕习语 这个习语是最受欢迎的习语之一,因为 ...

  2. JUnit中测试异常抛出的方法

    最近在做TWU关于TDD的作业,对JUnit中测试异常抛出的方法进行了一些学习和思考. 在进行单元测试的时候有的时候需要测试某一方法是否抛出了正确的异常.例如,我有一个方法,里面对一个List进行读取 ...

  3. Junit中的异常测试

    Junit中的异常测试 参考文章: (1)Junit中的异常测试 (2)https://www.cnblogs.com/pengshuangbao/p/6366478.html 备忘一下.

  4. Win11dns异常怎么修复?Win11修复dns异常的三种方法

    ​DNS服务异常就是服务器故障,找不到服务器的地址.常会出现的问题诸如网络故障.网站故障.电脑DNS设置错误等,那么对于DNS异常应该怎么修复呢?今天小编将为大家分享Win11修复DNS异常的三种方法 ...

  5. Win11的两个实用技巧系列之解决dns异常的三种方法、win10/win11卡顿的三种解决办法

    电脑dns异常怎么修复win10? Win10解决dns异常的三种方法 电脑dns异常怎么修复win10?最近有很多win10用户遇到dns配置错误的问题,这让用户非常苦恼,下面我们就来看看Win10 ...

  6. java多线程同步的四种方法_java中实现多线程的两种方法

    java多线程有几种实现方法,都是什么?同步有几种实java中多线程的实现方法有两种:1.直接继承thread类:2.实现runnable接口:同步的实现方法有五种:1.同步方法:2.同步代码块:3. ...

  7. 在JavaScript中重复字符串的三种方法

    In this article, I'll explain how to solve freeCodeCamp's "Repeat a string repeat a string" ...

  8. 在js中加html_在HTML文档中嵌入JavaScript的四种方法

    在HTML里嵌入JavaScript 在HTML文档里嵌入客户端JavaScript代码有4中方法: 1.内嵌,放置在标签之间  (少): 2.放置在有 3.放置自HTML事件处理程序中,该事件处理程 ...

  9. html怎么样取jsp中的路径,jsp中获得路径的两种方法和获得url路径的方法(推荐)

    是解决相对路径的问题,可返回站点的根路径. //这样获得的是绝对路径 //这样获得的是相对路径 能够更有效的防治连接的失效. request.getContextPath()得到的是项目的名字,如果项 ...

最新文章

  1. PEInfo编程思路讲解03 - 工具篇03|解密系列
  2. How to uninstall git
  3. golang基本数据类型默认值
  4. 新工具上线!只需2步助你轻松学爬虫!
  5. 分布式与人工智能课程(part13)--模型验证
  6. java实践_Java怪异实践
  7. 用SublimeText当Unity Shader的编辑器
  8. RAD与non-RAD
  9. 字符串数组排序的快速排序实现
  10. 1.直流无刷电机BLDC转速计算推论
  11. JAVA学习篇--静态代理VS动态代理
  12. [转贴]比《同居密友》更搞笑的【阿奴与唐玉】陶海风格
  13. NI LabVIEW开发环境(2.生成installer安装程序exe)
  14. 基金指数温度怎么算_投资指数基金的奇技淫巧——指数温度实战详解
  15. 常见的计算机专业的复合命题例子,第五章、复合命题.ppt
  16. 转载 禁止ie浏览器打开
  17. 准确率、召回率、F值
  18. 2023年JAVA JDK8的安装与配置(附JAVA8安装包)
  19. openstack跟着官网部署过程
  20. 判断输入是否为电话号码

热门文章

  1. 怎样批量获取文件名,批量提取文件名 文件名读取windows 批处理文件
  2. 19年8月 字母哥 第二章 RESTFul接口实现与测试 看到这里了
  3. 多智能体强化学习_基于多智能体强化学习主宰星际争霸游戏
  4. ES6 Map对象的使用
  5. MySQL优化(四):count()
  6. 会话技术Session
  7. etl介绍与etl工具比较_ETL万岁
  8. apache spark_Apache Spark软件包,从XML到JSON
  9. vue 脚手架测试环境_关于单元测试脚手架的几点思考
  10. Hibernate锁定模式– PESSIMISTIC_READ和PESSIMISTIC_WRITE如何工作