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人岗匹配测评

oppo人岗匹配测评_在测试中使用匹配器相关推荐

  1. 严格匹配_2020湖北省考招录“刚柔并济”强调“人岗匹配”

    6月23日,2020湖北省考公告发布,预示着2020湖北省考招录工作正式启动.本次考录计划招录公务员(参公人员)共计8103人.中公教育专家在仔细对比了2020湖北省考公告与往年的公告后发现,今年湖北 ...

  2. e成科技人岗匹配中的匹配模型

    随着网络招聘的发展与壮大,网聘渠道积攒着数亿份个人简历以及上千万份企业招聘信息.如何将这些简历和岗位进行精准匹配是各大招聘平台面临的重大挑战. 问题描述 在人岗匹配中,JD文档由多句工作描述和岗位要求 ...

  3. 做好人岗匹配,实现业绩增长

    索尼公司创始人盛田昭夫之所以被称为"经营之圣",是因为他非常重视对员工的情感激励.工作期间,盛田昭夫一直保持着和员工一起吃工作餐.聊天的习惯,以便深入了解员工所需. 某天晚上,盛田 ...

  4. 【CIKM 2020】基于多视图协作学习的人岗匹配研究

    点击上方,选择星标或置顶,每天给你送干货! 阅读大概需要16分钟 跟随小博主,每天进步一丢丢 来自:RUC AI BOX 近日,第29届国际计算机学会信息与知识管理大会(CIKM 2020)在线上召开 ...

  5. CIKM 2020 | 基于多视图协作学习的人岗匹配研究

    论文简介 论文:Learning to Match Jobs with Resumes from Sparse Interaction Data using Multi-View Co-Teachin ...

  6. AI得贤招聘官:浅谈人岗匹配对招聘的影响

    对于企业来说,招聘工作不可或缺.人岗匹配是招聘环节中的一个核心问题,也是检验招聘成果的一大关键指标.人岗匹配,简言之,如何招聘到合适的人才,一直是HR所不断探索的招聘课题. 招聘的人员与岗位不匹配,会 ...

  7. 一文速览人岗匹配领域研究进展

    每天给你送来NLP技术干货! © 作者|郑博文 机构|中国人民大学高瓴人工智能学院 来自:RUC AI Box 本文主要从文本匹配.历史行为偏好建模以及混合推荐三个角度介绍了当前人岗匹配中的主要模型与 ...

  8. 科学使用人才,做到人岗匹配

    为了摆脱危机,迎接挑战,企业只有优化自己的内部行为,解决市场化与国际化的融合问题,才能从根本上使企业转机. 但是一个企业光有人力资本的积累是远远不够的,还必须对其进行有效配置和合理使用,做到人岗匹配, ...

  9. ​RecSys 2022 | 面向人岗匹配的双向选择偏好建模

    本文为 BOSS 直聘联合中国人民大学提出的建模双边选择偏好的人岗匹配模型.目前,该论文已被推荐系统国际会议 RecSys 2022 接收. 论文标题: Modeling Two-Way Select ...

最新文章

  1. 【Paper】2017_Limit-Cycle-Based Decoupled Design of Circle Formation Control with Collision Avoidance
  2. 文本编辑器中菜单栏删除功能的实现
  3. 提高ASP.NET应用程序性能的几招方法
  4. 验证控件jQuery Validation Engine调用外部函数验证
  5. 遍历mysql大表的小技巧
  6. Conda 环境常用碎笔记
  7. MacBook Pro 如何删除多余专注模式?
  8. linux 格式化 lvm2,fedora 23 lvm2格式 根目录磁盘空间不足 扩容方法
  9. 数独超难题目_超难数独基本解题法
  10. 罗技键盘+android风格,Logitech 罗技 K480 蓝牙键盘,IOS、OSX 和安卓三大系统使用体验...
  11. 纸带打点计算机是什么原理,从电火花打点计时器高清拆解图,分析构造,详细解读电路工作原理...
  12. Qt 编译时遇到 error: [debug/qrc_music.cpp] Error 1
  13. jQuery动画效果
  14. 华为5G旗舰Mate30来了!这款5G“重磅炸弹”意义何在?
  15. 计算机联锁系统故障处理流程图,铁路TYJL Ⅱ型计算机联锁操作流程图
  16. eclipse中刷新项目
  17. 小黑仿生轮腿机器人(三)-SLAM导航
  18. 杰理之BQB 的 profile 测试【篇】
  19. 【linux】can‘t set line discipline
  20. css怎么设置z坐标,CSS 定位(postion、z-index)

热门文章

  1. crawlspider解析,并使用crawlspider爬取八一中文网小说
  2. AirServer自动接收多画面投屏或者跨设备投屏
  3. Modelsim之 DO文件简介
  4. Axure绘制轮播图
  5. Enbean Ebean ORM JDBC Suport
  6. C++实现坦克大战(新手思路)
  7. 还在用PPT?XMind 8 Update 9 思维导图安装教程,赶紧收藏(亲测有效)
  8. 微软AI插件Github Copilot初体验
  9. JSON 语法之JSON 布尔值
  10. 官宣:2021年计算机技术与软件考试工作安排及报名时间等说明