1. 概述
Hamcrest 是一个提供匹配器(matchers)方法的库,能帮助开发者编写更简洁的单元测试。它包含大量匹配器,你可以先通过这篇文章了解基础用法。
本文将重点探讨Bean 匹配器——专门用于验证 POJO 对象属性的利器。
2. 环境配置
引入 Hamcrest 只需在 pom.xml
中添加以下 Maven 依赖:
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>java-hamcrest</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
最新版本可在 Maven Central 查询。
3. Bean 匹配器实战
Bean 匹配器是验证 POJO 属性的瑞士军刀,在单元测试中高频使用。先创建测试用的 City
类:
public class City {
String name;
String state;
// 标准构造器、getter/setter
}
3.1. hasProperty
匹配器
✅ 核心功能:验证 Bean 是否包含指定名称的属性
@Test
public void givenACity_whenHasProperty_thenCorrect() {
City city = new City("San Francisco", "CA");
assertThat(city, hasProperty("state"));
}
测试通过,因为 City
类确实存在 state
属性。
进阶用法:同时验证属性值
@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
匹配器
当需要批量验证多个属性时,创建期望对象比逐个断言更高效:
@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
工具方法
需要动态检查类结构时,这个工具方法能获取属性描述符:
@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")));
}
PropertyDescriptor
对象包含属性元数据,这里我们验证了 getter 方法名。
3.4. propertyDescriptorsFor
工具方法
批量获取所有属性描述符,可指定类层级深度:
@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"));
}
关键步骤:
- 获取从
City
到Object
层级的所有属性描述符 - 用 Java 8 Stream 提取 getter 方法名
- 通过集合匹配器验证结果(更多集合匹配器见这里)
4. 总结
Hamcrest 匹配器是每个项目的必备工具,学习曲线平缓但见效极快。
Bean 匹配器尤其擅长简化 POJO 验证,这正是单元测试中的高频需求。掌握这些工具能显著提升测试代码的可读性和维护性。
完整示例代码请参考 GitHub 项目。