JUnit的内置Hamcrest Core Matcher支持

在用JUnit和Hamcrest改进assertEquals的文章中,我简要讨论了Hamcrest “ 核心 ”匹配器与JUnit的现代版本“结合”在一起的情况。 在那篇文章中,我特别关注了JUnit的assertThat(T,Matcher)静态方法与Hamcrest核心is()匹配器的结合使用,该方法自动包含在更高版本的JUnit中。 在本文中,我将介绍与最新版本的JUnit捆绑在一起的其他Hamcrest“核心”匹配器。

JUnit的包括开箱即用的Hamcrest “核心”匹配器的两个优点是,无需专门下载Hamcrest,也无需在单元测试类路径中明确包含它。 在查看更多方便的Hamcrest“核心”匹配器之前,重要的是要在此指出,我有意重复提及“核心” Hamcrest匹配器,因为JUnit的最新版本仅提供“核心”( 并非全部 )Hamcrest匹配器自动。 仍然需要单独下载核心匹配器之外的任何Hamcrest匹配器,并在单元测试类路径上明确指定。 了解什么是Hamcrest“核心”(以及在最新版本的JUnit中默认情况下可用的匹配器)的一种方法是查看该程序包的基于Javadoc的API文档 :

从JUnit提供的org.hamcrest.core软件包的文档中,我们可以找到以下匹配器(及其描述):

Javadoc类说明 盖在这里?
AllOf <T> 计算两个匹配器的逻辑和。
AnyOf <T> 计算两个匹配器的逻辑和。
DescribedAs <T> 为另一个匹配器提供自定义描述。
是<T> 装饰另一个Matcher,保留其行为,但允许测试更具表现力。 再次
IsAnything <T> 始终返回true的匹配器。 没有
IsEqual <T> 根据Object.equals(java.lang.Object)invokedMethod测试,该值是否等于另一个值?
IsInstanceOf 测试值是否为类的实例。
IsNot <T> 计算匹配器的逻辑取反。
IsNull <T> 值是否为空?
IsSame <T> 该值与另一个值是同一对象吗?

在我先前的演示Hamcrest is()匹配器与JUnit的assertThat()结合使用的文章中,我使用了IntegerArithmetic实现作为测试文件。 我将在这里再次使用它来演示其他一些Hamcrest核心匹配器。 为了方便起见,该类在下面复制。

IntegerArithmetic.java

package dustin.examples;/*** Simple class supporting integer arithmetic.* * @author Dustin*/
public class IntegerArithmetic
{/*** Provide the product of the provided integers.* * @param firstInteger First integer to be multiplied.* @param secondInteger Second integer to be multiplied.* @param integers Integers to be multiplied together for a product.* @return Product of the provided integers.* @throws ArithmeticException Thrown in my product is too small or too large*     to be properly represented by a Java integer.*/public int multiplyIntegers(final int firstInteger, final int secondInteger, final int ... integers){int returnInt = firstInteger * secondInteger;for (final int integer : integers){returnInt *= integer;}return returnInt;}
}

在“ 使用JUnit和Hamcrest改进assertEquals”中 ,我主要依靠is()来将预期结果与测试的整数乘法的实际结果进行比较。 另一个选择是使用equalTo匹配器,如下面的代码清单所示。

使用Hamcrest equalTo()

/*** Test of multiplyIntegers method, of class IntegerArithmetic, using core* Hamcrest matcher equalTo.*/@Testpublic void testWithJUnitHamcrestEqualTo(){final int[] integers = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};final int expectedResult = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 *13 * 14 * 15;final int result = this.instance.multiplyIntegers(2, 3, integers);assertThat(result, equalTo(expectedResult));}

尽管不是必需的,但一些开发人员喜欢将isequalTo一起使用,因为它对他们来说更流利。 这就是is存在的原因:更流畅地使用其他匹配器。 我经常equalTo()使用is() (暗示equalTo() ),如通过JUnit和Hamcrest改善对assertEquals所述 。 下一个示例演示了将is()匹配器与equalTo匹配器结合使用。

将Hamcrest equalTo()与is()结合使用

/*** Test of multiplyIntegers method, of class IntegerArithmetic, using core* Hamcrest matcher equalTo with "is" Matcher..*/@Testpublic void testWithJUnitHamcrestEqualToAndIsMatchers(){final int[] integers = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};final int expectedResult = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 *13 * 14 * 15;final int result = this.instance.multiplyIntegers(2, 3, integers);assertThat(result, is(equalTo(expectedResult)));}

equalTo Hamcrest匹配器执行类似于调用Object.equals(Object)的比较。 实际上,其比较功能依赖于底层对象的equals(Object)实现的使用。 这意味着最后两个示例将通过,因为所比较的数字在逻辑上是等效的。 当想要确保更大的身份相等性时(实际上是相同的对象,而不仅仅是相同的逻辑内容),可以使用Hamcrest sameInstance匹配器,如下面的代码清单所示。 因为断言是正确的,所以也应用了not匹配器,因为只有预期的和实际的结果并非相同,实例才通过测试,只有“否”通过测试。

使用Hamcrest sameInstance()和not()

/*** Test of multiplyIntegers method, of class IntegerArithmetic, using core* Hamcrest matchers not and sameInstance.*/@Testpublic void testWithJUnitHamcrestNotSameInstance(){final int[] integers = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};final int expectedResult = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 *13 * 14 * 15;final int result = this.instance.multiplyIntegers(2, 3, integers);assertThat(result, not(sameInstance(expectedResult)));}

有时需要控制从失败的单元测试的断言中输出的文本。 JUnit包括核心Hamcrest匹配器asDescribed()来支持此功能。 下一个清单中显示了这样的代码示例,代码清单后的NetBeans IDE的屏幕快照中显示了失败测试(和相应的断言)的输出。

将Hamcrest asDescribed()与sameInstance()一起使用

/*** Test of multiplyIntegers method, of class IntegerArithmetic, using core* Hamcrest matchers sameInstance and asDescribed. This one will assert a* failure so that the asDescribed can be demonstrated (don't do this with* your unit tests as home)!*/@Testpublic void testWithJUnitHamcrestSameInstanceDescribedAs(){final int[] integers = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};final int expectedResult = 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * 11 * 12 *13 * 14 * 15;final int result = this.instance.multiplyIntegers(2, 3, integers);assertThat(result,describedAs("Not same object (different identity reference)",sameInstance(expectedResult)));}

当关联的单元测试断言失败时,使用describedAs()可以报​​告更有意义的消息。

现在,我将使用另一个人为设计的类来帮助说明在最新版本的JUnit中可用的其他核心Hamcrest匹配器。 接下来显示“需要测试”。

SetFactory.java

package dustin.examples;import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;/*** A Factory that provides an implementation of a Set interface based on* supplied SetType that indicates desired type of Set implementation.* * @author Dustin*/
public class SetFactory<T extends Object>
{public enum SetType{ENUM(EnumSet.class),HASH(HashSet.class),SORTED(SortedSet.class), // SortedSet is an interface, not implementationTREE(TreeSet.class),RANDOM(Set.class);       // Set is an interface, not a concrete collectionprivate Class setTypeImpl = null;SetType(final Class newSetType){this.setTypeImpl = newSetType;}public Class getSetImplType(){return this.setTypeImpl;}}private SetFactory() {}public static SetFactory newInstance(){return new SetFactory();}/*** Creates a Set using implementation corresponding to the provided Set Type* that has a generic parameterized type of that specified.* * @param setType Type of Set implementation to be used.* @param parameterizedType Generic parameterized type for the new set.* @return Newly constructed Set of provided implementation type and using*    the specified generic parameterized type; null if either of the provided*    parameters is null.* @throws ClassCastException Thrown if the provided SetType is SetType.ENUM,*    but the provided parameterizedType is not an Enum.*/public Set<T> createSet(final SetType setType, final Class<T> parameterizedType){if (setType == null || parameterizedType == null){return null;}Set<T> newSet = null;try{switch (setType){case ENUM:if (parameterizedType.isEnum()){newSet = EnumSet.noneOf((Class<Enum>)parameterizedType);}else{throw new ClassCastException("Provided SetType of ENUM being supplied with "+ "parameterized type that is not an enum ["+ parameterizedType.getName() + "].");}break;case RANDOM:newSet = LinkedHashSet.class.newInstance();break;case SORTED:newSet = TreeSet.class.newInstance();break;default:newSet = (Set<T>) setType.getSetImplType().getConstructor().newInstance();break;}}catch (  InstantiationException| IllegalAccessException| IllegalArgumentException| InvocationTargetException| NoSuchMethodException ex){Logger.getLogger(SetFactory.class.getName()).log(Level.SEVERE, null, ex);}return newSet;}
}

刚刚显示了代码的人为设计的类提供了使用其他Hamcrest“核心”匹配器的机会。 如上所述,可以将所有这些匹配与is匹配器一起使用,以提高语句的流畅性。 两个有用的“核心”的匹配是nullValue()notNullValue()这两者在未来基于JUnit的代码列表被证实(和is结合使用在一种情况下)。

使用Hamcrest nullValue()和notNullValue()

/*** Test of createSet method, of class SetFactory, with null SetType passed.*/@Testpublic void testCreateSetNullSetType(){final SetFactory factory = SetFactory.newInstance();final Set<String> strings = factory.createSet(null, String.class);assertThat(strings, nullValue());}/*** Test of createSet method, of class SetFactory, with null parameterized type* passed.*/@Testpublic void testCreateSetNullParameterizedType(){final SetFactory factory = SetFactory.newInstance();final Set<String> strings = factory.createSet(SetType.TREE, null);assertThat(strings, is(nullValue()));}@Testpublic void testCreateTreeSetOfStringsNotNullIfValidParams(){final SetFactory factory = SetFactory.newInstance();final Set<String> strings = factory.createSet(SetType.TREE, String.class);assertThat(strings, notNullValue());}

Hamcrest匹配器instanceOf也很有用,并在下一个代码清单中进行演示(一个单独使用instanceOf的示例和一个与is结合使用的示例)。

使用Hamcrest instanceOf()

@Testpublic void testCreateTreeSetOfStringsIsTreeSet(){final SetFactory factory = SetFactory.newInstance();final Set<String> strings = factory.createSet(SetType.TREE, String.class);assertThat(strings, is(instanceOf(TreeSet.class)));}@Testpublic void testCreateEnumSet(){final SetFactory factory = SetFactory.newInstance();final Set<RoundingMode> roundingModes = factory.createSet(SetType.ENUM, RoundingMode.class);roundingModes.add(RoundingMode.UP);assertThat(roundingModes, instanceOf(EnumSet.class));}

到目前为止,许多Hamcrest核心匹配器都提供了更高的流畅性和可读性,但出于更多原因,我喜欢接下来的两个匹配器。 Hamcrest hasItem()匹配器检查集合中指定项的存在,甚至更有用的Hamcrest hasItems()匹配器检查集合中多个规定项的存在。 在代码中更容易看到这一点,下面的代码演示了它们的实际作用。

使用Hamcrest hasItem()和hasItems()

@Testpublic void testCreateTreeSetOfStringsHasOneOfAddedStrings(){final SetFactory factory = SetFactory.newInstance();final Set<String> strings = factory.createSet(SetType.TREE, String.class);strings.add("Tucson");strings.add("Arizona");assertThat(strings, hasItem("Tucson"));}@Testpublic void testCreateTreeSetOfStringsHasAllOfAddedStrings(){final SetFactory factory = SetFactory.newInstance();final Set<String> strings = factory.createSet(SetType.TREE, String.class);strings.add("Tucson");strings.add("Arizona");assertThat(strings, hasItems("Tucson", "Arizona"));}

有时需要测试某种测试方法的结果,以确保它满足各种各样的期望。 这就是Hamcrest allOf匹配器派上用场的地方。 此匹配器确保所有条件(表示为匹配器)都为真。 在下面的代码清单中对此进行了说明,该清单使用一个断言测试生成的Set不为null,其中包含两个特定的String,并且它是TreeSet的实例。

使用Hamcrest allOf()

@Testpublic void testCreateSetAllKindsOfGoodness(){final SetFactory factory = SetFactory.newInstance();final Set<String> strings = factory.createSet(SetType.TREE, String.class);strings.add("Tucson");strings.add("Arizona");assertThat(strings,allOf(notNullValue(), hasItems("Tucson", "Arizona"), instanceOf(TreeSet.class)));}

为了演示Hamcrest核心“ anyOf”匹配器为JUnit的较新版本提供了开箱即用的功能,我将使用另一个需要单元测试的可笑的Java类。

今天.java

package dustin.examples;import java.util.Calendar;
import java.util.Locale;/*** Provide what day of the week today is.* * @author Dustin*/
public class Today
{/*** Provide the day of the week of today's date.* * @return Integer representing today's day of the week, corresponding to*    static fields defined in Calendar class.*/public int getTodayDayOfWeek(){return Calendar.getInstance(Locale.US).get(Calendar.DAY_OF_WEEK);}
}

现在,我需要测试上述类中的唯一方法是否正确返回了代表星期几的有效整数。 我希望我的测试确保返回代表星期天到星期六的一天的有效整数,但是要测试的方法是这样的,使得它可能与任何给定的测试运行都不是一周中的同一天。 下面的代码清单指示如何使用包含JUnit的Hamcrest“ anyOf”匹配器进行测试。

使用Hamcrest anyOf()

/*** Test of getTodayDayOfWeek method, of class Today.*/@Testpublic void testGetTodayDayOfWeek(){final Today instance = new Today();final int todayDayOfWeek = instance.getTodayDayOfWeek();assertThat(todayDayOfWeek,describedAs("Day of week not in range.",anyOf(is(Calendar.SUNDAY),is(Calendar.MONDAY),is(Calendar.TUESDAY),is(Calendar.WEDNESDAY),is(Calendar.THURSDAY),is(Calendar.FRIDAY),is(Calendar.SATURDAY))));}

尽管Hamcrest的allOf要求所有条件都必须匹配才能避免断言,但任何一个条件的存在足以确保anyOf不会导致失败的断言。

我最喜欢的确定JUnit可用的Hamcrest核心匹配器的方法是在Java IDE中使用导入完成。 当我静态导入org.hamcrest.CoreMatchers.*软件包内容时,将显示所有可用的匹配器。 我可以在IDE中查看*代表什么,以查看对我可用的匹配器。

JUnit包含Hamcrest“核心”匹配器真是太好了,这篇文章试图演示其中的大多数。 Hamcrest在“核心”之外提供了许多有用的匹配器,它们也很有用。 有关详细信息,请参见Hamcrest教程 。

参考:在Inspired by Actual Events博客上,我们的JCG合作伙伴 Dustin Marx提供了JUnit的内置Hamcrest Core Matcher支持 。


翻译自: https://www.javacodegeeks.com/2012/06/junits-built-in-hamcrest-core-matcher.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/372589.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java开发高性能网站需要关注的事

转自&#xff1a;http://www.javabloger.com/java-development-concern-those-things/ 近期各家IT媒体举办的业内技术大会让很多网站都在披露自己的技术内幕与同行们分享&#xff0c;大到facebook&#xff0c;百度&#xff0c;小到刚起步的网站。facebook&#xff0c;百度之类的…

并发–顺序线程和原始线程

我不久前参与了一个项目&#xff0c;该项目的报告流程如下&#xff1a; 用户会要求举报 报告要求将被翻译成较小的部分 每个零件的报告将基于零件/节的类型由报告生成器生成 组成报告的各个部分将重新组合成最终报告&#xff0c;并返回给用户 我的目标是展示如何从错误的实…

linux夏令时配置文件,Linux夏令时是怎么调整的?

以法国巴黎为例&#xff1a;root121 zoneinfo]# ln -s /usr/share/zoneinfo/Europe/Paris /etc/localtime[root121 zoneinfo]# date2015年 10月 13日 星期二 03:45:09 CEST[root121 zoneinfo]# date -RTue, 13 Oct 2015 03:45:31 0200[root121 zoneinfo]# zdump -v /etc/localt…

Kali Linux渗透基础知识整理(二)漏洞扫描

Kali Linux渗透基础知识整理系列文章回顾 漏洞扫描 网络流量NmapHping3NessuswhatwebDirBusterjoomscanWPScan网络流量 网络流量就是网络上传输的数据量。 TCP协议 TCP是因特网中的传输层协议&#xff0c;使用三次握手协议建立连接。当主动方发出SYN连接请求后&#xff0c;等待…

嵌入式软件设计第09实验报告

学号&#xff1a;140201133 姓名&#xff1a;李宇昕 组别&#xff1a;第3组 实验地点&#xff1a;D19 一、实验目的&#xff1a; 1.熟悉WWW技术中的SSI&#xff08;Server Side Include&#xff09;技术。 2.学会使用SSI技术编写代码把当前开发板内…

TeamCity工件:HTTP,Ant,Gradle和Maven

您可以通过几种方式检索TeamCity工件&#xff1f; 我说有很多选择 &#xff01; 如果您使用的是Java构建工具&#xff0c;那么可以使用简单的HTTP请求&#xff0c;Ant Ivy&#xff0c;Gradle和Maven下载和使用TeamCity构建配置生成的二进制文件。 怎么样&#xff1f; 继续阅读…

AutoCAD如何方便截图放到Word文档,改成白底黑字

将模型视图切换到布局2即可 比如下图所示的效果 先回到模型视图把所有线条颜色都改成白色&#xff0c;然后添加适当的标注&#xff08;比如要受力分析&#xff0c;则在CAD中绘制箭头也很方便的&#xff09;&#xff0c;文字说明。然后切换到布局2就OK 可以截图了。 转载于:http…

iOS--支付宝环境集成

1.下载支付宝SDK以及Demo https://doc.open.alipay.com/doc2/detail?treeId54&articleId103419&docType1 2.新建文件夹“AliSDK”&#xff0c;将压缩包内的文件拷贝到该文件夹下&#xff0c;完成后如下图所示&#xff1a; 3.将文件夹拷贝到项目中&#xff0c; 4.执行完…

Java EE 6测试第二部分– Arquillian和ShrinkWrap简介

在Java EE 6测试的第一部分中&#xff0c;我简要介绍了使用Glassfish嵌入式容器的EJB 3.1 Embeddable API&#xff0c;以演示如何启动该容器&#xff0c;如何在项目类路径中查找bean以及运行非常简单的集成测试。 这篇文章重点介绍Arquillian和ShrinkWrap以及为什么它们是用于企…

【腾讯Bugly干货分享】Android内存优化总结实践

本文来自于腾讯Bugly公众号&#xff08;weixinBugly&#xff09;&#xff0c;未经作者同意&#xff0c;请勿转载&#xff0c;原文地址&#xff1a;https://mp.weixin.qq.com/s/2MsEAR9pQfMr1Sfs7cPdWQ 导语 智能手机发展到今天已经有十几个年头&#xff0c;手机的软硬件都已经发…

令人印象深刻的第一个Apache Camel版本

为了准备下周的CamelOne会议&#xff0c;我花了一些时间回顾一下Apache Camel项目的历史。 因此&#xff0c;除其他外&#xff0c;我了解了Apache Camel的第一个正式1.0版本 。 Apache Camel 1.0 – 5年前 我看的越多&#xff0c;这个版本的事实给我留下了深刻的印象。 现在您…

为什么在2012/2013年我将在新的Enterprise Java项目中继续使用Spring *和* Java EE

自从我担任技术决策职务以来已经过去了一年多&#xff0c;很高兴看到我仍然与之保持着完美的和谐。 几个月前&#xff0c;我在KaiWhner的一个不错的博客中写了一个有关JEE与Spring的答案。 如果观点没有不同&#xff0c;那么讨论的附加值在哪里&#xff1f; 我确实同意Kai的许多…

linux ubuntu 五笔输入法,ubuntu下安装fcitx五笔输入法

安装fcitx输入法sudo add-apt-repository ppa:fcitx-team/stable #添加安装源&#xff0c;apt-get 添加&#xff0c;nightly源也可以sudo apt-get update #更新源&#xff0c;否则无法安装fcit…

浅谈Windows下SVN在Android Studio中的配置、基本使用及解除关联

看到网上很多关于svn环境配置和关联Android-Studio的很多博文&#xff0c;发现很零散&#xff0c;想集大家所长整理一下&#xff1a; 在AndroidStudio中开发版本控制中&#xff0c;除了Git就是SVN&#xff0c;和Eclipse不同Android Studio没有提供单独的插件&#xff0c;只能和…

四. 基于环视Camera的BEV感知算法-BEVDepth

目录 前言0. 简述1. 算法动机&开创性思路2. 主体结构3. 损失函数4. 性能对比总结下载链接参考 前言 自动驾驶之心推出的《国内首个BVE感知全栈系列学习教程》&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考 本次课程我们来学习下课程第四章——基于环视Cam…

【腾讯Bugly干货分享】Android Patch 方案与持续交付

本文来自于腾讯bugly开发者社区&#xff0c;非经作者同意&#xff0c;请勿转载&#xff0c;原文地址&#xff1a;http://dev.qq.com/topic/57a31921ac3a1fb613dd40f3 Android 不仅系统版本众多&#xff0c;机型众多&#xff0c;而且各个市场都各有各的政策和审核速度&#xff0…

App Engine中的Google Services身份验证,第1部分

这篇文章将说明如何构建一个简单的Google App Engine&#xff08;GAE&#xff09;Java应用程序&#xff0c;该应用程序可针对Google进行身份验证&#xff0c;并利用Google的OAuth授权访问Google的API服务&#xff08;例如Google Docs&#xff09;。 此外&#xff0c;在Google已…

山东自考c语言程序设计停考了吗,2018山东自考停考专业有哪些

自考每年都会停考一批的专业以适应社会的发展&#xff0c;今年山东自考的停考专业有哪些&#xff1f;本文由学梯网小编整理发布&#xff0c;仅供参考。2018年山东自考停考专业有什么根据山东省教育考试院发布的《关于山东自学考试停考国际贸易(专科)等19个专业的通知》知悉&…

公开调用私有Java方法?

我们是Java开发人员&#xff0c;在Java中已知4种访问修饰符&#xff1a;私有&#xff0c;受保护&#xff0c;公共和包。 好吧&#xff0c;除了私有外&#xff0c;最后三个可以通过继承&#xff0c;相同的包或实例从类外部调用。 现在&#xff0c;常见的问题是&#xff0c;可以公…

C语言字符像素,返回字符串宽度 (以像素为单位)

[c]代码库#include #include #include #include int main(void){/* request auto detection */int gdriver DETECT, gmode, errorcode;int x 0, y 0;int i;char msg[80];/* initialize graphics and local variables */initgraph(&gdriver, &gmode, "");/…