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列表中的内容。您可以在此处 找到有关集合匹配器的更多信息。