Java Hamcrest学习

Posted FserSuN

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java Hamcrest学习相关的知识,希望对你有一定的参考价值。

1 概述

在Java生态中,Hamcrest是一个用在单元测试中的框架。该框架与JUnit集成。

Java中使用JUnit进行单元测试。JUnit提供了若干断言工具。 如assertEquals、assertTrue等。此外我们还可以通过扩展能力来增强assert*的表达。这时我们使用

assertThat
public static void assertThat(T actual,Matcher<? super T> matcher)

通过指定不同的matcher,来判断actual对象是否满足验证条件。例如验证0不是1,下面的表达的更清晰易懂。

assertThat(“Zero is one”, 0, is(not(1))) // passes

我们可以自己去实现matcher。但Hamcrest这个框架已给我们实现了很多常用的matcher,从而简化我们的使用。

2 依赖

Junit 4.8.2 已经内部集成了hamcrest,所以不需要添加额外依赖。但提供的工具有限。此外可以引入all包,使用更多的工具。

<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-all</artifactId>
    <version>1.3</version>
</dependency>

3 第一个样例

public class StringMatcherTest 
    
    @Test
    public void given2Strings_whenEqual_thenCorrect() 
        String a = "foo";
        String b = "FOO";
        assertThat(a, equalToIgnoringCase(b));
    

从语义表达上,显然使用hamcrest提供的matcher含义更清晰。接下来我们将看几种matcher。

4 Object Matcher

如果要验证任意的Java对象我们可以使用Object Matcher。例如验证对象的toString方法是否等于某个值。此外也可以验证一个类是否是另一个类的子类

@Test
public void givenBean_whenToStringReturnsRequiredString_thenCorrect()
    Person person=new Person("Barrack", "Washington");
    String str=person.toString();
    assertThat(person,hasToString(str));


@Test
public void given2Classes_whenOneInheritsFromOther_thenCorrect()
        assertThat(Cat.class,typeCompatibleWith(Animal.class));
    

5 Bean Matcher

我们可以通过bean matcher来检查java bean的属性

public class Person 
    String name;
    String address;

    public Person(String personName, String personAddress) 
        name = personName;
        address = personAddress;
    


// 检查是否有属性name

@Test
public void givenBean_whenHasValue_thenCorrect() 
    Person person = new Person("Baeldung", 25);
    assertThat(person, hasProperty("name"));


// 检查地址属性address等于New York

@Test
public void givenBean_whenHasCorrectValue_thenCorrect() 
    Person person = new Person("Baeldung", "New York");
    assertThat(person, hasProperty("address", equalTo("New York")));


// 检查两个Person对象是否有相同值

@Test
public void given2Beans_whenHavingSameValues_thenCorrect() 
    Person person1 = new Person("Baeldung", "New York");
    Person person2 = new Person("Baeldung", "New York");
    assertThat(person1, samePropertyValuesAs(person2));

6 Collection Matcher

collection Matcher可以用来验证集合

验证集合是否为空

@Test
public void givenCollection_whenEmpty_thenCorrect() 
    List<String> emptyList = new ArrayList<>();
    assertThat(emptyList, empty());


验证集合大小
@Test
public void givenAList_whenChecksSize_thenCorrect() 
    List<String> hamcrestMatchers = Arrays.asList(
      "collections", "beans", "text", "number");
    assertThat(hamcrestMatchers, hasSize(4));


检查是否包含指定元素,而不关注顺序

@Test
public void givenAListAndValues_whenChecksListForGivenValues_thenCorrect() 
    List<String> hamcrestMatchers = Arrays.asList(
      "collections", "beans", "text", "number");
    assertThat(hamcrestMatchers,
    containsInAnyOrder("beans", "text", "collections", "number"));


验证包含元素且顺序正确
@Test
public void givenAListAndValues_whenChecksListForGivenValuesWithOrder_thenCorrect() 
    List<String> hamcrestMatchers = Arrays.asList(
      "collections", "beans", "text", "number");
    assertThat(hamcrestMatchers,
    contains("collections", "beans", "text", "number"));



检查一个数组是否含有指定元素
@Test
public void givenArrayAndValue_whenValueFoundInArray_thenCorrect() 
    String[] hamcrestMatchers =  "collections", "beans", "text", "number" ;
    assertThat(hamcrestMatchers, hasItemInArray("text"));

7 Number Matcher

Number matcher用来指定进行数值验证

验证1大于0
@Test
public void givenAnInteger_whenGreaterThan0_thenCorrect() 
    assertThat(1, greaterThan(0));


小于等于验证
@Test
public void givenAnInteger_whenLessThanOrEqTo5_thenCorrect() 
    assertThat(-1, lessThanOrEqualTo(5));


8 Text Matcher

Text Matcher 字符串验证

是否是空字符串
@Test
public void givenString_whenEmpty_thenCorrect() 
    String str = "";
    assertThat(str, isEmptyString());




是否含有空包符
@Test
public void given2Strings_whenEqualRegardlessWhiteSpace_thenCorrect() 
    String str1 = "text";
    String str2 = " text ";
    assertThat(str1, equalToIgnoringWhiteSpace(str2));

9 Core API

Hamcrest core API 提供了一些很优雅的工具类,使得我们的单元测试可读性更好。
此外还有一些核心matcher简化我们的使用。

使用is
@Test
public void given2Strings_whenIsEqualRegardlessWhiteSpace_thenCorrect() 
    String str1 = "text";
    String str2 = " text ";
    assertThat(str1, is(equalToIgnoringWhiteSpace(str2)));


使用not
@Test
public void given2Strings_whenIsNotEqualRegardlessWhiteSpace_thenCorrect() 
    String str1 = "text";
    String str2 = " texts ";
    assertThat(str1, not(equalToIgnoringWhiteSpace(str2)));


验证两个类是否是一个实例
@Test
public void given2Objects_whenSameInstance_thenCorrect() 
    Cat cat=new Cat();
    assertThat(cat, sameInstance(cat));

10 自定义Matcher

除了使用框架提供的matcher,我们还可以自定义matcher。我们自定义类继承TypeSafeMatcher类并实现对应的方法即可。

public class IsPositiveInteger extends TypeSafeMatcher<Integer> 

    public void describeTo(Description description) 
        description.appendText("a positive integer");
    

    @Factory
    public static Matcher<Integer> isAPositiveInteger() 
        return new IsPositiveInteger();
    

    @Override
    protected boolean matchesSafely(Integer integer) 
        return integer > 0;
    


11 总结

阅读完原文,重点是理解Hamcrest是什么,用来解决什么问题,整个过程就很好理解了。其次通过框架提供的几个matcher介绍基本使用。最后学习自定义matcher的用法。

参考

[1].https://www.baeldung.com/java-junit-hamcrest-guide
[2].http://tutorials.jenkov.com/java-unit-testing/matchers.html
[3].http://hamcrest.org/JavaHamcrest/tutorial

以上是关于Java Hamcrest学习的主要内容,如果未能解决你的问题,请参考以下文章

Software Testing Lab 1

java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribeing

JUNIT,HAMCREST,ECLEMMA单元测试基础(JAVA)

Junit,hamcrest,eclemma单元测试基础(java)

java Hamcrest Matchers

java 自定义IsEmpty Hamcrest Matcher