Contents

Hamcrest 匹配器简介

1. 概述

**Hamcrest 是一个提供方法(称为匹配器)的库,可帮助开发人员编写更简单的单元测试。**有很多匹配器,您可以从这里 阅读其中的一些开始。

在本文中,我们将探讨 beans 匹配器。

2. 设置

要获取 Hamcrest,我们只需要将以下 Maven 依赖项添加到我们的pom.xml中:

<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>java-hamcrest</artifactId>
    <version>2.0.0.0</version>
    <scope>test</scope>
</dependency>

最新的 Hamcrest 版本可以在Maven Central 上找到。

3. Bean匹配器

Bean 匹配器对于检查 POJO 的条件非常有用,这是编写大多数单元测试时经常需要的东西。

在开始之前,我们将创建一个类来帮助我们完成示例:

public class City {
    String name;
    String state;
    // standard constructor, getters and setters
}

现在我们都准备好了,让我们看看 beans 匹配器的实际效果!

3.1. hasProperty

这个匹配器基本上是检查某个 bean 是否包含由属性名称标识的特定属性:

@Test
public void givenACity_whenHasProperty_thenCorrect() {
    City city = new City("San Francisco", "CA");
    
    assertThat(city, hasProperty("state"));
}

所以,这个测试将会通过,因为我们的City bean 有一个名为state 的属性。

按照这个思路,我们也可以测试一个bean是否有某个属性,那个属性是否有某个值:

@Test
public void givenACity_whenHasPropertyWithValueEqualTo_thenCorrect() {
    City city = new City("San Francisco", "CA");

    assertThat(city, hasProperty("name", equalTo("San Francisco")));
}

正如我们所见,hasProperty被重载并且可以与第二个匹配器一起使用来检查属性的特定条件。

所以,我们也可以这样做:

@Test
public void givenACity_whenHasPropertyWithValueEqualToIgnoringCase_thenCorrect() {
    City city = new City("San Francisco", "CA");
    assertThat(city, hasProperty("state", equalToIgnoringCase("ca")));
}

有用吧?我们可以通过接下来要探索的匹配器将这个想法更进一步。

3.2. samePropertyValuesAs

有时当我们必须检查一个 bean 的很多属性时,创建一个具有所需值的新 bean 可能更简单。然后,我们可以检查测试 bean 和新 bean 之间的相等性。当然,Hamcrest 为这种情况提供了匹配器:

@Test
public void givenACity_whenSamePropertyValuesAs_thenCorrect() {
    City city = new City("San Francisco", "CA");
    City city2 = new City("San Francisco", "CA");
    assertThat(city, samePropertyValuesAs(city2));
}

这导致更少的断言和更简单的代码。同样,我们可以测试否定的情况:

@Test
public void givenACity_whenNotSamePropertyValuesAs_thenCorrect() {
    City city = new City("San Francisco", "CA");
    City city2 = new City("Los Angeles", "CA");
    assertThat(city, not(samePropertyValuesAs(city2)));
}

接下来,我们将看到几个用于检查类属性的实用方法。

3.3. getPropertyDescriptor

**在某些情况下,探索类结构可能会派上用场。**Hamcrest 提供了一些实用方法来做到这一点:

@Test
public void givenACity_whenGetPropertyDescriptor_thenCorrect() {
    City city = new City("San Francisco", "CA");
    PropertyDescriptor descriptor = getPropertyDescriptor("state", city);
    assertThat(descriptor
      .getReadMethod()
      .getName(), is(equalTo("getState")));
}

**对象descriptor检索有关属性state的大量信息。**在这种情况下,我们提取了 getter 的名称并断言它等于某个预期值。请注意,我们还可以应用其他文本匹配器。

继续,我们将探讨的最后一种方法是同一想法的更一般情况。

3.4. propertyDescriptorsFor

此方法与上一节中的方法基本相同**,但是针对 bean 的所有属性**。我们还需要指定我们希望在类层次结构中达到多高:

@Test
public void givenACity_whenGetPropertyDescriptorsFor_thenCorrect() {
    City city = new City("San Francisco", "CA");
    PropertyDescriptor[] descriptors = propertyDescriptorsFor(
      city, Object.class);
 
    List<String> getters = Arrays.stream(descriptors)
      .map(x -> x.getReadMethod().getName())
      .collect(toList());
    assertThat(getters, containsInAnyOrder("getName", "getState"));
}

因此,我们在这里所做的是:从 bean city中获取所有属性描述符并停在Object级别。

然后,我们只是使用 Java 8 的功能来过滤 getter 方法。

最后,我们使用集合匹配器来检查getters列表中的内容。您可以在此处 找到有关集合匹配器的更多信息。