断言框架:Hamcrest


Hamcrest 介绍

  • Hamcrest(官网)是一个以测试为目的,能组合灵活表达式的匹配器类库,主要用于编写断言的框架。它可以与 JUnit 框架配合使用,使断言可读更高、更加灵活(例如判断数组、集合、Map 中的内容等)。

  • Hamcrest 提供了大量被称为“匹配器”的方法。每个匹配器都设计用于执行特定的比较操作。

  • Hamcrest 的可扩展性强,能够创建自定义的匹配器。

  • 支持多种语言:Java、Python、Ruby、Object-C、Php、Erlang、Swift 等,本文以使用 JAVA 为例。


Hamcrest 常用匹配器

Maven 依赖

<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest</artifactId>
    <version>2.2</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.20</version>
    <scope>provided</scope>
</dependency>

字符串匹配器

方法名 用法 说明
equalTo assertThat(testedValue, equalTo(expectedValue)); 断言被测的 testedValue 是否等于 expectedValue。
equalTo 可用于断言数值之间、字符串之间、对象之间的比较,相当于 Object 的 equals 方法
equalToIgnoringCase assertThat(testedString, equalToIgnoringCase(expectedString)); 断言被测的字符串 testedString 在忽略大小写的情况下等于 expectedString
equalToIgnoringWhiteSpace assertThat(testedString, equalToIgnoringWhiteSpace(expectedString); 断言被测的字符串 testedString 在忽略头尾的任意个空格的情况下等于 expectedString
containsString assertThat(testedString, containsString(subString)); 断言被测的字符串 testedString 包含子字符串 subString
endsWith assertThat(testedString, endsWith(suffix)); 断言被测的字符串 testedString 以子字符串 suffix 结尾
startsWith assertThat(testedString, startsWith(prefix)); 断言被测的字符串 testedString 以子字符串 prefix 开始
anything assertThat("随便是个啥", anything("总是匹配就完事了")); 总是匹配

数值匹配器

方法名 用法 说明
closeTo assertThat(testedDouble, closeTo(20.0, 0.5)); 断言被测的浮点型数testedDouble在 20.0-0.5 ~ 20.0+0.5 范围之内
greaterThan assertThat(testedNumber, greaterThan(16.0)); 断言被测的数值 testedNumber 大于 16.0
lessThan assertThat(testedNumber, lessThan(16.0)); 断言被测的数值 testedNumber 小于 16.0
greaterThanOrEqualTo assertThat(testedNumber, greaterThanOrEqualTo (16.0)); 断言被测的数值 testedNumber 大于等于 16.0
lessThanOrEqualTo assertThat(testedNumber, lessThanOrEqualTo(16.0)); 断言被测的 testedNumber 小于等于 16.0

集合匹配器

方法名 用法 说明
hasEntry assertThat(mapObject, hasEntry("key", "value" )); 断言被测的 Map 对象 mapObject 含有一个键值为 "key" 对应元素值为 "value" 的 Entry 项
hasItem assertThat(iterableObject, hasItem(element)); 表明被测的迭代对象 iterableObject 含有元素 element 项则测试通过
hasKey assertThat(mapObject, hasKey("key")); 断言被测的 Map 对象 mapObject 含有键值 "key"
hasValue assertThat(mapObject, hasValue(value)); 断言被测的 Map 对象 mapObject 含有元素值 value

对象匹配器

方法名 用法 说明
hasToString assertThat(true, hasToString(equalTo("true"))); 断言被测对象的 toString 方法结果等于 "true"
instanceOf assertThat("string", instanceOf(String.class)); 断言被测对象属于字符串类
typeCompatibleWith assertThat(Integer.class, typeCompatibleWith(Number.class)); 断言 Integer 类兼容 Number 类
sameInstance Integer number = new Integer(200);
assertThat(number, sameInstance(number));
断言被测对象与 number 对象属于同一实例
hasProperty assertThat(new MyClass(), hasProperty("name")); 断言被测对象含有 name 属性

逻辑匹配器

方法名 用法 说明
nullValue assertThat(object, nullValue()); 断言被测 object 的值为 null
notNullValue assertThat(object, notNullValue()); 断言被测 object 的值不为 null
is assertThat(testedString, is(equalTo(expectedValue))); 断言被测的 object 等于后面给出匹配表达式
is 匹配符简写应用之一 assertThat(testedValue, is(expectedValue)); is(equalTo(x)) 的简写,断言 testedValue 等于 expectedValue
is 匹配符简写应用之二 assertThat(testedObject, is(Cheddar.class)); is(instanceOf(SomeClass.class)) 的简写,断言 testedObject 为 Cheddar 的实例
not assertThat(testedString, not(expectedString)); 与 is 匹配符正好相反,断言被测的 object 不等于后面给出的 object
allOf assertThat(testedNumber, allOf(greaterThan(8), lessThan(16))); 断言符合所有条件,相当于 "与"(&&)
anyOf assertThat(testedNumber, anyOf(greaterThan(16), lessThan(8))); 断言符合条件之一,相当于 "或"(||)

自定义匹配器

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;

/**
 * 自定义匹配器,判断年龄范围在 [1,200] 返回 true
 * 1、继承 TypeSafeMatcher 并指定泛型
 * 2、重写 matchesSafely、describeTo 方法
 * 3、提供外部调用的静态方法
 */
public class IsNormalAgeRange extends TypeSafeMatcher<Integer> {

    @Override
    public boolean matchesSafely(Integer number) {
        return number >=1 && number <= 200;
    }
    
    @Override
    public void describeTo(Description description) {
        description.appendText("need to be within [1, 200]");
    }

    public static Matcher normalAgeRange() {
        return new IsNormalAgeRange();
    }

}

测试:

@Test
public void testMyMatcher() {
    assertThat(100, IsNormalAgeRange.normalAgeRange());
}
posted @ 2021-11-01 16:56  Juno3550  阅读(536)  评论(0编辑  收藏  举报