matchers依赖

介绍

上一次 ,我讨论了Hamcrest Matcher是什么,如何使用以及如何制作。 在本文中,我将解释创建Hamcrest Matchers的更多高级步骤。 首先,我将分享如何使您的匹配器更易于类型安全,然后介绍无状态匹配器的一些技术,最后是如何减少测试类的大量静态导入。 我还将给出一些有关命名静态工厂方法的快速提示。

类型安全匹配器

您可能已经在上次开发的matchs()方法中注意到了,我在注释中指出,我曾使用“ yoda条件”来避免null检查和类型检查。 首先,自己对yoda条件进行一些研究不会有什么坏处(我可能有一天会发表一篇有关它的文章,但不能保证),但是这里要注意的最大事情是某种类型检查和需要空检查。 这是因为matchs()方法接受一个对象,而不是泛型参数中指定的类型。

如Hamcrest的文档中所述:

此方法与Object匹配,而不是与通用类型T匹配。这是因为Matcher的调用者在运行时不知道类型是什么(由于Java通用类型已擦除类型)。

因此,我们需要确定传入的对象的类型。此外,我们还应确保没有传入任何空值(除非我们的特定Matcher可以这样做,但这非常罕见),或者在至少要确保传入的null不会导致NullPointerException。

但是有一种更简单的方法:TypeSafeMatcher。 如果扩展该类而不是BaseMatcher类,它将为您执行类型检查和null检查,然后将对象传递给仅采用泛型指定类型的匹配方法。

定义TypeSafeMatcher非常类似于我们上次定义Matcher的方式,但有一些区别:除了覆盖matchs()之外,您还可以替代使用通用类型而不是Object的matchesSafely()。 而不是覆盖describeMismatch(),而是覆盖describeMismatchSafely()。 可能没有一个新的describeTo()可能令人惊讶,但是看到它除了Description之外没有其他内容,因此不需要类型安全的版本。

否则,创建TypeSafeMatcher几乎是相同的。

不过,我不得不提我上周忘记的事情。 定义自己的Matcher的人不需要重写describeMismatch()或describeMismatchSafely()方法。 BaseMatcher和TypeSafeMatcher都具有那些方法的默认实现,这些方法的简单实现是仅输出“ was item.toString() ”(如果TypeSafeMatcher获得错误类型的项,则“ was of itemClassNameitem.toString()” )”。

这些默认实现通常足够好,但是如果要使用的类型没有toString()的有用实现,则使用您自己的不匹配消息来描述该项目的问题显然更有用。 即使类具有不错的toString()实现,我也总是这样做,因为它可以更快地解决问题。

有关其他可扩展匹配器类的说明

Hamcrest核心库中还有其他几个Matcher类,供用户从中扩展。 这些有几种口味。

首先,是CustomMatcher和CustomTypeSafeMatcher。 这些设计用于通过匿名类一次性创建Matchers。 他们可能是有用的,但我更愿意总是在情况下,正确执行我曾经确实需要它一次。

接下来,有DiagnosingMatcher和TypeSafeDiagnosingMatcher,它们使您可以在match()方法中创建不匹配描述。 这似乎是用一块石头杀死两只鸟的好方法,但是我有几块牛肉:1)它违反了SRP 2)如果存在不匹配,它再次调用matchs()方法只是为了填充在不匹配说明中。 因此,第一个调用忽略获取描述,第二个调用忽略匹配。

您可以扩展的最后一个特殊的Matcher是FeatureMatcher。 这可能非常有用,但要理解起来很复杂(我不确定自己是否正确理解–直到我尝试自己动手做一个或阅读如何做一个为止)。 如果我弄清楚并获得了很好的理解,我将在这里为您写另一篇文章。

无状态匹配器

任何不需要将任何内容传递给其构造函数的Matcher(因此,它是静态工厂方法)都是无状态Matcher。 它们与其他Matcher相比有一个很小的优势,因为您只需要在任何时候存在一个实例,就可以在需要使用该Matcher的任何时间重用它。

这是一个非常简单的补充。 您需要做的就是创建该类的静态实例,并使您的静态工厂返回该实例,而不是调用构造函数。 库实际附带的IsEmptyString Matcher可以做到这一点(上一次我们的示例没有这样做,但是为了简单起见)。

减少静态进口数量

用Hamcrest Matchers编写了相当多的测试后,您可能会注意到文件顶部有很多静态导入。 一段时间后,这可能会成为很大的麻烦事,所以让我们看一下可以减轻此问题的方法。

实际上,这几乎与上一个解决方案一样简单。 您可以通过创建实质上为您执行此操作的新类来减少静态导入。 这个新类具有烦人的静态导入,但随后定义了自己的静态工厂方法来委托给原始对象。 这是将一些核心Matchers组合到一个地方的示例:

import org.hamcrest.core.IsEqual;
import org.hamcrest.core.IsNull;
import org.hamcrest.core.IsSame;
import org.hamcrest.Matcher;public class CoreMatchers
{public static  Matcher equalTo(T object) {return IsEqual.equalTo(object);}public static Matcher notNullValue() {return IsNull.notNullValue();}public static  Matcher notNullValue(Class type) {return IsNull.notNullValue(type);}public static Matcher nullValue() {return IsNull.nullValue();}public static  Matcher nullValue(Class type) {return IsNull.nullValue(type);}public static  Matcher sameInstance(T target) {return IsSame.sameInstance(target);}public static  Matcher theInstance(T target) {return IsSame.theInstance(target);}
}

然后,要使用任何或所有Matcher,只需静态导入CoreMatchers。*还有一种生成这些组合Matcher类的方法,如官方Hamcrest教程所示 。 我不会继续讨论它,因为它不在本文讨论范围之内,而且我也不喜欢它。

结束提示:命名

如果您阅读了官方的Hamcrest教程和/或查看了内置的Matchers,您可能会注意到静态工厂方法的命名趋势。 通用语法匹配“断言testObjectfactoryMethod ”。 方法名称的语法通常设计为可以在“ is”之前使用的当前时态动作。在命名自己的静态工厂方法时,通常应遵循此约定,但实际上我建议将“ is”放入名称中已经。 这样,Matcher的用户无需将您的方法嵌套在is()方法内。 但是,如果执行此操作,则还需要创建反函数。 允许使用is()方法包装Matcher的原因是,因此您也可以将其包装在not()方法中,以测试已经测试的内容的逆函数。 这将导致类似“断言testObject不是factoryMethod ”的句子。如果您认为遵循约定对特定的Matcher过于严格,则只需确保使用当前的时态操作测试即可。 例如,我做了一个匹配器,检查是否抛出了一个异常,该异常的静态工厂方法是throwsA()。 我只是不喜欢将它命名为throwingA()以便与“ is”一起使用。 但是,如果再次违反约定,则必须确定要创建一个静态静态工厂方法。 例如,如果您要实现自己的逆工厂,最简单的方法通常是用not()包装正工厂。 因此,我的nottThrowA()方法将返回not(throwsA())。 不过要小心:有时候,将正负误转实际上并不能给出您想要的正确逆。

奥托罗

好吧,这就是我为您准备的。 如果您想让我继续谈论Hamcrest Matchers,请在评论中告诉我。 否则,您可以在其github页面上的Hamcrest Matchers上进行自己的研究。下周,我将讨论如何让您的Hamcrest Matchers以类似于AssertJ断言的流畅方式检查多个事情。

翻译自: https://www.javacodegeeks.com/2015/01/advanced-creation-of-hamcrest-matchers.html

matchers依赖

matchers依赖_Hamcrest Matchers的高级创建相关推荐

  1. matchers依赖_Hamcrest Matchers教程

    matchers依赖 本文是我们名为" 用Mockito测试 "的学院课程的一部分. 在本课程中,您将深入了解Mockito的魔力. 您将了解有关"模拟",&q ...

  2. matchers依赖_Hamcrest Matchers,Guava谓词和Builder设计模式

    matchers依赖 通常,在编码时,我们必须处理其中包含数十个字段的一些POJO对象. 很多时候,我们通过一个带有数十个参数的构造函数来初始化这些类,这以任何可能的想象的方式都是可怕的. 除此之外, ...

  3. matchers依赖_定制Hamcrest Matchers

    matchers依赖 本文是我们名为" 用Mockito测试 "的学院课程的一部分. 在本课程中,您将深入了解Mockito的魔力. 您将了解有关"模拟",&q ...

  4. Hamcrest Matchers的高级创建

    介绍 上一次 ,我讨论了Hamcrest Matcher是什么,如何使用以及如何制作. 在本文中,我将解释创建Hamcrest Matchers的更多高级步骤. 首先,我将分享如何使您的匹配器更易于类 ...

  5. 【Spring 工厂】反转控制与依赖注入、Spring工厂创建复杂对象3种方式

    反转控制与依赖注入 反转控制 与 依赖注入 反转控制(IOC Inverse of Control) 依赖注入 (Dependency Injection - DI) Spring工厂创建复杂对象(3 ...

  6. factorybean 代理类不能按照类型注入_彻底搞懂依赖注入(一)Bean实例创建过程

    点击上方"Java知音",选择"置顶公众号" 技术文章第一时间送达! 上一章介绍了Bean的加载过程(IOC初始化过程),加载完成后,紧接着就要用到它的依赖注入 ...

  7. Angular 依赖注入 useClass 的实例创建位置

    用@NgModule在providers定义了MyService token用useClass来提供: MyNewService的初始化过程: InjectionToken: this.records ...

  8. java启动依赖包问题_spring boot创建项目包依赖问题的解决

    今天捣腾了spring boot,按照官网案例,缺发现本地无论包依赖出现问题,并且无法启动,一整天在踩maven的坑,记录下这个血的教训. 1.spring-core依赖包问题 运行applicati ...

  9. Hamcrest Matchers教程

    本文是我们名为" 用Mockito进行测试 "的学院课程的一部分. 在本课程中,您将深入了解Mockito的魔力. 您将了解有关"模拟","间谍&qu ...

最新文章

  1. Centos7 安装maven3.5.0和git
  2. React Native之箭头函数和延展操作符(...)
  3. shell中获取单个文件大小
  4. 6.Half Lambert光照Diffuse Shader
  5. Apache骆驼丝攻示例
  6. 【IMX6UL开发板试用体验】上手试用与资源使用
  7. python语言三角函数_python中三角函数_Python中的三角函数
  8. 黄色光纤跳线、橙色光纤跳线、蓝色光纤跳线区别
  9. 金刚石结构的各向异性
  10. R语言详解参数检验和非参数检验——样本T检验、方差分析、pearson相关性检验、单样本wilcoxon检验、Mann-Whitney检验、配对样本wilcoxon检验、列联表检验、卡方检验
  11. 我们通常所说的利率是指_我们通常所说的利率是指()。 A.市场利率B.名义利率C.实际利率D.固定利率...
  12. 个人发卡网全开源修复版源码
  13. Stream流的学习
  14. 哈罗单车确认完成新一轮几十亿融资 春华资本与蚂蚁金服领投
  15. 原创|一个统计查询模块基于设计模式的抽象设计
  16. 10个迷惑新手的Cocoa,Objective-c开发难点和问题 39|MX21k
  17. vue 给取data值_vue获取data值的方式分析
  18. 74LS273内部逻辑结构
  19. python语音输入转化成文字_利用百度语音识别接口将语音转换成文字教程
  20. 渲染有问题?怎么办?6种方法让你渲染无忧

热门文章

  1. CF140C-New Year Snowmen【优先队列】
  2. [XSY]Illyasviel的图游戏(博弈论)
  3. [XSY] 相似(DP套DP)
  4. 27、jdbc操作数据库(4)
  5. 9、java中的异常处理机制
  6. Tomcat 的 Server 文件配置详解
  7. 20 个使用 Java CompletableFuture的例子
  8. Java多线程神器:join使用及原理
  9. mvc.net分页查询案例——PagedList
  10. 捕获异常VS抛出异常