使用JUnit的ExpectedException和@Rule测试自定义异常
为什么要测试异常流? 就像所有代码一样,测试覆盖率会在代码和应该生成的业务功能之间写一个合同,从而为您提供代码的有效文档 ,以及增加的尽早且经常强调功能的功能。 我不会介绍测试的许多好处,而是只关注异常测试。
有很多方法可以测试从一段代码引发的异常流。 假设您有一个受保护的方法,该方法要求参数不为null。 您将如何测试该状况? 引发异常时,如何防止JUnit报告失败? 该博客涵盖了几种不同的方法使用JUnit的的ExpectedException使用JUnit的@rule功能实现的高潮。
“旧”方式
在不久的将来,测试异常的过程需要大量的样板代码,您可以在其中启动try / catch块,如果代码未产生预期的行为,则报告失败,然后捕获异常以查找异常。具体类型。 这是一个例子:
public class MyObjTest {@Testpublic void getNameWithNullValue() {try {MyObj obj = new MyObj();myObj.setName(null);fail('This should have thrown an exception');} catch (IllegalArgumentException e) {assertThat(e.getMessage().equals('Name must not be null'));}}
}
从这个旧示例中可以看到,测试用例中的许多行只是为了支持缺少专门测试异常处理的功能。 使用try / catch方法的一个好处是可以测试特定消息和预期异常上的任何自定义字段 。 我们将通过JUnit的ExpectedException和@Rule注释进一步探讨这一点。
JUnit添加了预期的异常
JUnit通过添加@Test注释字段“ expected”来响应用户对异常处理的需求。 目的是,如果引发的异常类型与注释中存在的异常类匹配,则整个测试用例将通过。
public class MyObjTest {@Test(expected = IllegalArgumentException.class)public void getNameWithNullValue() {MyObj obj = new MyObj();myObj.setName(null);}
}
从较新的示例中可以看到,样板代码要少得多,并且测试非常简洁,但是存在一些缺陷 。 主要缺陷是测试条件太宽泛。 假设签名中有两个变量,并且两个变量都不能为null,那么如何知道为IllegalArgumentException抛出了哪个变量呢? 当您扩展了Throwable并需要检查字段的存在时会发生什么? 在继续阅读时,请记住这些,随后将有解决方案。
JUnit @Rule和ExpectedException
如果查看前面的示例,可能会看到期望抛出IllegalArgumentException,但是如果您有一个自定义异常,该怎么办? 如果要确保该消息包含特定的错误代码或消息怎么办? 这是JUnit真正出色的地方,它提供了专门为异常测试量身定制的JUnit @Rule对象。 如果您不熟悉JUnit @Rule,请在此处阅读文档 。
ExpectedException
JUnit提供了一个JUnit类ExpectedException,该类旨在用作@Rule。 ExpectedException允许您的测试声明预期会出现异常,并为您提供一些基本的内置功能来清楚地表达预期的行为。 与@Test(expected)批注功能不同,ExpectedException类允许您通过Hamcrest匹配器库测试特定的错误消息和自定义字段。
JUnit的ExpectedException的示例
import org.junit.rules.ExpectedException;public class MyObjTest {@Rulepublic ExpectedException thrown = ExpectedException.none();@Testpublic void getNameWithNullValue() {thrown.expect(IllegalArgumentException.class);thrown.expectMessage('Name must not be null');MyObj obj = new MyObj();obj.setName(null);}
}
如前所述,该框架允许您测试特定消息,以确保在测试专门寻找的情况下抛出异常。 当怀疑多个参数的可空性时,这将非常有用。
自定义字段
可以说,ExpectedException框架最有用的功能是能够使用Hamcrest匹配器测试您的自定义/扩展异常。 例如,您有一个自定义/扩展的异常将被抛出到一个方法中,并且该异常内部有一个“ errorCode”。 如何在不从上面列出的try / catch块中引入样板代码的情况下测试该功能? 定制匹配器怎么样!
可以从以下网址获得此代码: https : //github.com/mike-ensor/custom-exception-testing
解决方案:首先是测试用例
import org.junit.rules.ExpectedException;public class MyObjTest {@Rulepublic ExpectedException thrown = ExpectedException.none();@Testpublic void someMethodThatThrowsCustomException() {thrown.expect(CustomException.class);thrown.expect(CustomMatcher.hasCode('110501'));MyObj obj = new MyObj();obj.methodThatThrowsCustomException();}
}
解决方案:自定义匹配器
import com.thepixlounge.exceptions.CustomException;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;public class CustomMatcher extends TypeSafeMatcher<CustomException> {public static BusinessMatcher hasCode(String item) {return new BusinessMatcher(item);}private String foundErrorCode;private final String expectedErrorCode;private CustomMatcher(String expectedErrorCode) {this.expectedErrorCode = expectedErrorCode;}@Overrideprotected boolean matchesSafely(final CustomException exception) {foundErrorCode = exception.getErrorCode();return foundErrorCode.equalsIgnoreCase(expectedErrorCode);}@Overridepublic void describeTo(Description description) {description.appendValue(foundErrorCode).appendText(' was not found instead of ').appendValue(expectedErrorCode);}
}
注意:请访问https://github.com/mike-ensor/custom-exception-testing以获取可用的Hamcrest Matcher,JUnit @Rule和ExpectedException的副本。
在那里,您可以快速概览一下测试代码引发的异常的不同方法,以及从自定义异常类中测试特定消息和字段的能力。 请具体说明您的测试用例,并尝试针对您为测试设置的确切用例,请记住,测试可以避免引入副作用漏洞!
祝您编程愉快,别忘了分享!
参考:在Mike的站点博客上,从JCG合作伙伴 Mike 那里 ,使用JUnit的ExpectedException和@Rule测试自定义异常 。
翻译自: https://www.javacodegeeks.com/2012/10/testing-custom-exceptions-with-junits.html
使用JUnit的ExpectedException和@Rule测试自定义异常相关推荐
- junit rule_使用JUnit的ExpectedException和@Rule测试自定义异常
junit rule 异常测试 为什么要测试异常流? 就像所有代码一样,测试覆盖率在代码和应该产生的业务功能之间写了一个合同,从而为您提供了代码的有效文档 ,以及可以尽早且经常强调功能的附加功能. 我 ...
- 深入JUnit源码之Rule
初次用文字的方式记录读源码的过程,不知道怎么写,感觉有点贴代码的嫌疑.不过中间还是加入了一些自己的理解和心得,希望以后能够慢慢的改进,感兴趣的童鞋凑合着看吧,感觉JUnit这个框架还是值得看的,里面有 ...
- junit:junit_JUnit ExpectedException规则:超越基础
junit:junit JUnit测试中有多种处理异常的方法. 正如我在以前的一篇文章中所写的那样 ,我最好的方法是使用org.junit.rules.ExpectedException规则. 基本上 ...
- JUnit 3.8 通过反射测试私有方法
测试私有(private)的方法有两种: 1)把目标类的私有方法(修饰符:private)修改为(public),不推荐,因为修改了源程序不佳 2)通过反射 (推荐) 代码演示: 目标程序 Priva ...
- boost::safe_numerics模块实现测试自定义异常的测试程序
boost::safe_numerics模块实现测试自定义异常的测试程序 实现功能 C++实现代码 实现功能 boost::safe_numerics模块实现测试自定义异常的测试程序 C++实现代码 ...
- 使用JUnit 5进行Spring Boot测试
JUnit 5 (JUnit Jupiter)已经存在了相当长的一段时间,并且配备了许多功能. 但令人意外JUnit 5它不是一个默认的测试库相关,当涉及到春节开机测试入门:它仍然是JUnit 4.1 ...
- Junit单元测试不支持多线程测试问题全解析
一.背景 今天@段段提出了一个很好的问题,她发现单元测试时如果开多个线程,主线程运行结束就结束了,并不会等待子线程结束. 如果用main方法就没问题,技术群里展开了激烈的讨论. 本文将"复现 ...
- maven在idea中使用junit时,运行要测试的类,提示class not found。
maven在idea中使用junit时,运行要测试的类,提示class not found.需要把.idea配置文件删了,然后重启,之后就可以了
- junit return null该怎么测试_3 分钟生成一个单元测试报告,这个样式爱了
昨天有个小伙伴问我,有没有什么现成的测试报告模板,由于昨天实在比较忙就没顾上,所以今个有时间赶紧补上.一般力所能及的事,只要我有时间都会为大家解决,但毕竟能力有限做不到的地方小伙伴们也多理解. 在这里 ...
最新文章
- 利用CxImage实现编解码Gif图像代码举例
- 超级干货:关于数据中台的深度思考与总结
- python入门指南百度云-Python入门指南
- Chrome浏览器12px问题-webkit-text-size-adjust: none 已失效的解决方案
- DAS,NAS,SAN在数据库存储上的应用
- Yet another nio framework for java
- C++语言程序设计上机指导(二级),C++语言程序设计上机指导(二级)
- 三,springboot集成mybatis
- access两位小数不进位_人教版小学数学三年级下册笔算乘法(不进位)公开课优质课课件教案视频...
- 变量独立与不相关的区别
- 1017 A除以B (20 分)—PAT (Basic Level) Practice (中文)
- gridview中js的绑定问题 一个js的函数[转]
- Django实现websocket完成实时通讯,聊天室,在线客服等
- IPguard文档控制策略
- android 自定义 对号,超简单实现Android自定义Toast
- Android实现电子邮箱客户端
- 终极版Python打包exe文件,并修改图标,这将是你见过最详细的教程~
- windows逻辑卷扩容_Windows 动态磁盘卷:简单卷、跨区卷 、带区卷 、镜像卷 、RAID5卷 相关配置操作介绍...
- win7为什么打开桌面上的计算机很卡很慢,Win7电脑开机速度慢解决方法
- pc端编码表必须为gbk才能正常启动软件_【干货】请收下这份非常完整的PCIE4.0 发送端测试SOP...
热门文章
- tomcat(15)Digester库
- 阅读副本和Spring Data第2部分:配置基础项目
- 使用实例工厂方法实例化_一些工厂实例
- spring集成mq_使用Spring Integration Java DSL与Rabbit MQ集成
- 检测到基于堆栈的缓冲区溢出_检测到堆栈粉碎
- 到无限(溪流)和超越!
- unwind neo4j_Neo4j 2.1:传递节点ID与UNWIND
- camel 调用soap_使用Apache Camel通过soap添加WS-Security
- java8 linq4j_Java 8仍然需要LINQ吗? 还是比LINQ更好?
- java的对象对象映射_Java对象到对象映射器