oppo人岗匹配测评_在测试中使用匹配器

oppo人岗匹配测评

我们被迫在测试代码中写太多断言行的日子已经一去不复返了。 镇上有一个新的警长:assertThat和他的代理人:匹配者。 好吧,这不是什么新东西,但是无论如何,我想向您介绍匹配器的使用方式,然后对匹配器概念进行扩展,我发现在为我的代码开发单元测试时,匹配器概念非常有用。

首先,我将介绍匹配器的基本用法。 当然,您可以直接从其作者那里完整地了解hamcrest匹配器功能:
https://code.google.com/p/hamcrest/wiki/Tutorial 。

基本上,匹配器是定义两个对象何时匹配的对象。 通常,第一个问题是您为什么不使用等于? 好吧,有时您不想在它们的所有字段上都匹配两个对象,而只是在其中的某些字段上匹配,如果您使用旧代码,则会发现equals实现不存在或不符合您的预期。 另一个原因是使用assertThat为您提供了一种更加一致的“断言”方法,并且可以说是更具可读性的代码。 因此,例如,而不是编写:

int expected, actual;
assertEquals(expected, actual);

你会写

assertThat(expected, is(actual));

其中“ is”是静态导入的org.hamcrest.core.Is.is

并没有太大的区别……。 但是Hamcrest为您提供了许多非常有用的匹配器:

  • 对于数组和映射:hasItem,hasKey,hasValue
  • 数字:closeTo –一种指定相等性的方法,其边距误差大于,大于,小于…
  • 对象:nullValue,sameInstance

现在我们正在取得进步……Hamcrest匹配器的功能仍然是您可以为对象编写自己的匹配器。 您只需要扩展BaseMatcher <T>类。 这是一个简单的自定义匹配器的示例:

public class OrderMatcher extends BaseMatcher<Order> {private final Order expected;private final StringBuilder errors = new StringBuilder();private OrderMatcher(Order expected) {this.expected = expected;}@Overridepublic boolean matches(Object item) {if (!(item instanceof Order)) {errors.append("received item is not of Order type");return false;}Order actual = (Order) item;if (actual.getQuantity() != (expected.getQuantity())) {errors.append("received item had quantity ").append(actual.getQuantity()).append(". Expected ").append(expected.getQuantity());return false;}return true;}@Overridepublic void describeTo(Description description) {description.appendText(errors.toString());}@Factorypublic static OrderMatcher isOrder(Order expected) {return new OrderMatcher(expected);}
}

与旧的断言方法相比,这是一个全新的联盟。

因此,这简而言之就是Hamcrest的匹配器的用法。

但是,当我开始在现实生活中使用它时,尤其是在使用遗留代码时,我意识到故事还有很多。 这是使用匹配器时遇到的一些问题:

  1. 匹配器的结构可能非常重复且无聊。 我需要一种将DRY原理应用于匹配器代码的方法。
  2. 我需要一种统一的方式来访问匹配器。 默认情况下,框架应选择正确的匹配器。
  3. 我需要比较引用了另一个对象的对象,这些对象应该已经与匹配器进行了比较(对象引用可以根据需要进行深入处理)
  4. 我需要使用匹配器检查对象集合,而无需迭代该集合(也可以使用数组匹配器…,但我想要更多的J)
  5. 我需要一个更灵活的匹配器。 例如,对于同一个对象,我需要检查一组字段,但在另一种情况下,则需要检查另一组。 开箱即用的解决方案是为每种情况配备一个匹配器。 不喜欢那样

我使用了一些约定,知道了要应用哪个匹配器以及要比较或忽略哪个字段的匹配器层次结构,克服了这些问题。 此层次结构的根是扩展BaseMatcher <T>的RootMatcher <T>。

为了处理#1问题(重复代码),RootMatcher类包含所有匹配器的通用代码,例如用于检查实际值是否为null或与预期对象具有相同类型,甚至是相同类型的方法。同一实例:

public boolean checkIdentityType(Object received) {if (received == expected) {return true;}if (received == null || expected == null) {return false;}if (!checkType(received)){return false;}return true;}private boolean checkType(Object received) {if (checkType && !getClass(received).equals(getClass(expected))) {error.append("Expected ").append(expected.getClass()).append(" Received : ").append(received.getClass());return false;}return true;}

这将简化匹配器的编写方式,我不必考虑null或恒等角情况; 所有这些都在根类中解决了。

预期的对象和错误也位于根类中:

public abstract class RootMatcher extends BaseMatcher {protected T expected;protected StringBuilder error = new StringBuilder("[Matcher : " + this.getClass().getName() + "] ");

这样,您可以在扩展RootMatcher之后立即进入match方法的实现,而对于错误,只需将消息放入StringBuilder中即可。 RootMatcher将处理将它们发送到JUnit框架以呈现给用户的情况。

对于问题2(自动查找匹配项),解决方案采用其工厂方法:

@Factorypublic static  Matcher is(Object expected) {return getMatcher(expected, true);}public static  RootMatcher getMatcher(Object expected, boolean checkType) {try {Class matcherClass = Class.forName(expected.getClass().getName() + "Matcher");Constructor constructor = matcherClass.getConstructor(expected.getClass());return (RootMatcher) constructor.newInstance(expected);} catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) {}return (RootMatcher) new EqualMatcher(expected);}

如您所见,factory方法尝试使用两种约定来找出应该返回哪个匹配器

  1. 对象的匹配器具有对象名称+字符串Matcher
  2. 匹配器与要匹配的对象位于同一包中(建议位于同一包中,但在测试目录中)

使用此策略,我成功使用了一个匹配器:RootMatcher.is,它将为我提供所需的确切匹配器

为了解决对象关系(第3个问题)的递归性质,在检查对象字段时,我使用了RootManager中的方法来检查将使用匹配器的相等性:

public boolean checkEquality(Object expected, Object received) {String result = checkEqualityAndReturnError(expected, received);return result == null || result.trim().isEmpty();}public String checkEqualityAndReturnError(Object expected, Object received) {if (isIgnoreObject(expected)) {return null;}if (expected == null && received == null) {return null;}if (expected == null || received == null) {return "Expected or received is null and the other is not: expected " + expected + " received " + received;}RootMatcher matcher = getMatcher(expected);boolean result = matcher.matches(received);if (result) {return null;} else {StringBuilder sb = new StringBuilder();matcher.describeTo(sb);return sb.toString();}}

但是关于集合(问题4)呢? 为了解决这个问题,您要做的就是为扩展RootMatcher的集合实现匹配器。

因此,唯一剩下的问题是#5:使匹配器更加灵活,能够告诉匹配器它应该忽略哪个字段以及应该考虑哪个字段。 为此,我介绍了“ ignoreObject”的概念。 当匹配器在模板(预期对象)中找到对其的引用时,该对象将忽略该对象。 它是如何工作的? 首先,在RootMatcher中,我提供了用于返回任何Java类型的ignore对象的方法:

private final static Map ignorable = new HashMap();static {ignorable.put(String.class, "%%%%IGNORE_ME%%%%");ignorable.put(Integer.class, new Integer(Integer.MAX_VALUE - 1));ignorable.put(Long.class, new Long(Long.MAX_VALUE - 1));ignorable.put(Float.class, new Float(Float.MAX_VALUE - 1));}/*** we will ignore mock objects in matchers*/private boolean isIgnoreObject(Object object) {if (object == null) {return false;}Object ignObject = ignorable.get(object.getClass());if (ignObject != null) {return ignObject.equals(object);}return Mockito.mockingDetails(object).isMock();}@SuppressWarnings("unchecked")public static  M getIgnoreObject(Class clazz) {Object obj = ignorable.get(clazz);if (obj != null) {return (M) obj;}return (M) Mockito.mock(clazz);}@SuppressWarnings("unchecked")public static  M getIgnoreObject(Object obj) {return (M) getIgnoreObject(obj.getClass());}

如您所见,被忽略的对象将是被模拟的对象。 但是对于无法模拟的类(最终类),我提供了一些不太可能出现的任意固定值(可以对J进行改进)。 为此,开发人员必须使用RootMatcher中提供的equals方法:checkEqualityAndReturnError,它将检查是否忽略了对象。 使用我去年提出的这种策略和构建器模式( http://www.javaadvent.com/2012/12/using-builder-pattern-in-junit-tests.html ),我可以轻松地对复杂的结构做出断言目的:

import static […]RootMatcher.is;
Order expected = OrderBuilder.anOrder().withQuantity(2).withTimestamp(RootManager.getIgnoredObject(Long.class)).withDescription(“specific description”).build()
assertThat(order, is(expected);

如您所见,我可以轻松地指定应忽略时间戳记,这使我可以将同一匹配器与要验证的一组完全不同的字段一起使用。

确实,此策略需要进行大量准备,从而使所有构建者和匹配者都受益。 但是,如果我们要拥有经过测试的代码,并且要使测试成为主要关注应涵盖的测试流程的工作,那么我们需要这样的基础和这些工具来帮助我们轻松地建立前提条件和建立我们的预期状态。

当然,可以使用注释来改进实现,但是核心概念仍然存在。

我希望本文能帮助您改善测试风格,如果有足够的兴趣,我会尽力将完整的代码放在公共存储库中。

谢谢。

参考:来自Java日历日历博客的JCG合作伙伴 Stefan Bulzan 在测试中使用匹配器 。

翻译自: https://www.javacodegeeks.com/2013/12/using-matchers-in-tests.html

oppo人岗匹配测评

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

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

相关文章

【渝粤题库】陕西师范大学200041 文学概论 作业

《文学概论》作业 一、名词解释 1.文艺学 2.狭义文学 3.推陈出新 4.创作动机 5.文学本体论 6&#xff0e;艺术发现 7&#xff0e;艺术形式 8&#xff0e;现实型文学 9&#xff0e;典型 10&#xff0e;本文时间与故事时间 11&#xff0e;陌生化 12&#xff0e;剧本 13&#xf…

LaTeX indicator function

问题说明&#xff1a; \mathbb字符的空心化显示仅对字符有效&#xff0c;对数字无效。 解决方法&#xff1a; 1.使用 bbm 包 \documentclass{article} \usepackage{bbm} \begin{document}\[ \mathbbm{1} \]\end{document}2.使用 dsfont&#xff08;double stroke&#xff0…

【渝粤题库】陕西师范大学200471 英汉翻译

《英汉翻译》作业 I. Please translate the following phrases and the underlined part in each sentence. 1.break the record 2.armed to the teeth 3.sour grapes 4.a gentleman’s agreement 5.open door policy 6.the cold war 7.soft voice 8.soft fire 9. The poor acc…

JavaFX技巧31:遮罩/剪切/ Alpha通道

选择条 最近&#xff0c;我不得不实现一个自定义控件&#xff0c;该控件使用户可以从项目列表中选择一个项目。 此“ SelectionStrip”控件必须水平放置项目&#xff0c;并且在项目过多的情况下&#xff0c;允许用户左右水平滚动。 该控件将在空间受限的区域中使用&#xff0c;…

【渝粤题库】陕西师范大学200831 编译原理 作业

一、填空 1、预测分析方法LL&#xff08;1&#xff09;方法&#xff0c;它由一个栈&#xff0c;一个 和一个 组成。其中构造 是该分析方法的关键。 2、下面图 是一个DFA&#xff0c;而图 是一个NFA 3、词法分析器的任务是对 进行扫描&#xff0c;以 为依据识别出一个个单词符号…

通信中的频谱效率与能量效率

频谱效率(Spectral Efficiency) 频谱效率&#xff08;Spectral Efficiency&#xff0c;SE&#xff09;简称谱效&#xff0c;也称系统容量、频带利用率。 该指标用来衡量系统的有效性&#xff0c;描述了能够提供多少容量。 它定义为系统传输的有效信息速率R除以通信信道带宽B&a…

【渝粤题库】陕西师范大学201491 法学导论作业

《法学导论》作业 一、单项选择题 1&#xff0e;西方法学发展史上&#xff0c;著名法学家著作即学理法开始成为法律制度重要组成部分的是( ) A 古希腊 B古罗马 C近代 D现代 2&#xff0e;17-18世纪出现的资产阶级法权世界观的典型代表是( ) A 自然法学派 B历史法学派 C…

【渝粤题库】陕西师范大学201951 明清小说史 作业

单选题 1&#xff0e;将朝代兴替&#xff0c;争霸天下的题材组织成的长篇章回小说称作&#xff08; &#xff09; A、说铁骑 B、英雄传奇 C、历史演义 D、世情小说 2&#xff0e;以下见于《水浒传》的故事有&#xff08; &#xff09; A、智取生辰纲 B、火烧博望坡 C、弄权铁槛…

积分公式大全

https://kexue.fm/sci/integral/ 《积分公式大全》网络版本——By BoJone 引用原作者的话&#xff1a; 本附件所有公式来自《高等数学第三版》。   该书信息&#xff1a;同济大学数学教研室编&#xff0c;高等教育出版社&#xff0c;1988年4月第三版&#xff0c;ISBN 7-04-0…

注释嵌套注释_注释梦Night

注释嵌套注释XmlElementWrapper(name"orders") XmlJavaTypeAdapter(OrderJaxbAdapter.class) XmlElements({XmlElement(name"order_2",typeOrder2.class),XmlElement(name"old_order",typeOldOrder.class) }) JsonIgnore JsonProperty NotNull M…

【渝粤题库】国家开放大学2021春2312旅行社经营管理题目

试卷代号&#xff1a;2312 2021年春季学期期末统一考试 旅行社经营管理 试题 2021年7月 一、单项选择题&#xff08;下列各题选项中只有一个答案是最准确的&#xff0c;请将其序号埴入括号中&#xff0c;每小题2分.共20分&#xff09; 1.旅行社的( )是旅行社经营的基础&#xf…

Latex快速入门系列 -- 在TexStudio中正确插入参考文献的基本操作

目录 1 操作流程2 四种基本的文献格式比较3 文献数据库.bib的编写 1. 操作流程 1.1 创建文章主文件。Ctrl N 新建一个文件&#xff0c;Ctrl S 手动保存&#xff0c;保持文件后缀名.tex。得到一个.tex文件&#xff1a;文章名.tex&#xff0c;该文件用来编写你的文章的具体内…

【渝粤题库】国家开放大学2021春2509学前教育学题目

试卷代号&#xff1a;2509 2021年春季学期期末统一考试 学前教育学 试题 2021年7月 一、选择题&#xff08;每小题2分&#xff0c;共20分&#xff09; 1.瑞士教育家裴斯泰洛齐的代表作是( )。 A.《大教学论》 B.《世界图解》 C.《理想国》 D.《林哈德与葛笃德》 2.学前教育阻碍…

MongoDB索引策略和索引类型

1. MongoDB索引策略和索引类型–简介 MongoDB是一个开放源代码&#xff0c;面向文档的跨平台数据库&#xff0c;它使用C 开发&#xff0c;并且是最流行和使用最广泛的NoSQL类型数据库之一。 它可在具有键-值对的类JSON文档的顶部运行&#xff0c;其键值对在每个文档中都无法定义…

【渝粤题库】国家开放大学2021春2634推销策略与艺术题目

试卷代号&#xff1a;2634 2021年春季学期期末统一考试 推销策略与艺术 试题 2021年7月 一、单项选择&#xff08;在每小题的4个选项中选出一个最优的&#xff0c;将其序号填入题后括号内。每小题2分&#xff0c;共20分&#xff09; 1.在现代推销中&#xff0c;推销人员应该持有…

prove, verify, bear out, demonstrate, confirm, validate, testify, certify 的区别

1. prove prove “证明”&#xff0c;证明&#xff08;某事属实&#xff09;, 普通用词&#xff0c;泛指有充分的、可靠的事实证明某一观点或结论是正确的。可用作及物动词&#xff0c;后接宾语或宾语从句。 Galileo proved the law of falling objects to the world from the…

zeal刷新不出来_推进重涂市场标准化,立邦率先推出刷新服务“八大验收标准”...

点击蓝字【立邦中国】&#xff0c;设置星标关注。7月&#xff0c;立邦刷新服务率先在墙面重涂行业提出突破性的“八大验收标准”&#xff0c;根据不同的涂刷工艺来采用定制化的验收标准&#xff0c;更进一步推动重涂市场的标准化和规范化。自2011年推出立邦刷新服务至今&#x…

【渝粤题库】国家开放大学2021春2732土地利用规划题目

试卷代号&#xff1a;2732 2021年春季学期期末统一考试 土地利用规划 试题 2021年7月 一、单选题&#xff08;每小题3分&#xff0c;10小题&#xff0c;共30分&#xff09; 1.从生态角度看&#xff0c;土地不具有( )功能。 A.支撑 B.养育 C.净化 D.生产 2.土壤腐殖质的热容量比…

初学者指南:如何为Red Hat Process Automation Manager配置电子邮件服务任务

最近&#xff0c;我一直在更新我的免费在线研讨会 &#xff0c;特别是基于JBoss BPM Suite的系列研讨会 &#xff0c;以便您可以开始使用较新的Red Hat Process Automation Manager 。 在本文中&#xff0c;我将分享我在自动化项目中尝试使用电子邮件通知时偶然发现的内容。 …

【渝粤题库】国家开放大学2021春2786初级西方经济学题目

试卷代号&#xff1a;2786 2021年春季学期期末统一考试 初级西方经济学 试题 2021年7月 一、单项选择题&#xff08;在下列各题的备选答案中选择一个正确的&#xff0c;并将其序号字母填入题后的括号里。每题2分&#xff0c;共30分&#xff09; 1.如果某种商品缺乏弹性&#xf…