1. 概述
Hamcrest 提供了多种匹配器,让单元测试断言更简洁易读。 你可以在这里探索一些基础匹配器:Hamcrest 入门指南。
本篇教程将深入讲解对象匹配器的使用技巧。
2. 环境配置
要使用 Hamcrest,只需在 pom.xml
中添加以下 Maven 依赖:
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>java-hamcrest</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
最新版本可在 Maven 中央仓库 查询。
3. 对象匹配器
对象匹配器专门用于校验对象的属性。在深入之前,我们先创建两个示例类方便演示。
第一个类是 Location
,没有任何属性:
public class Location {}
第二个类 City
继承自 Location
,并添加了以下实现:
public class City extends Location {
String name;
String state;
// 标准构造器、getter 和 setter
@Override
public String toString() {
if (this.name == null && this.state == null) {
return null;
}
StringBuilder sb = new StringBuilder();
sb.append("[");
sb.append("Name: ");
sb.append(this.name);
sb.append(", ");
sb.append("State: ");
sb.append(this.state);
sb.append("]");
return sb.toString();
}
}
注意 City
继承了 Location
,这个关系后面会用到。现在开始探索对象匹配器!
3.1. hasToString
顾名思义,**hasToString
用于验证对象的 toString()
方法返回特定字符串**:
@Test
public void givenACity_whenHasToString_thenCorrect() {
City city = new City("San Francisco", "CA");
assertThat(city, hasToString("[Name: San Francisco, State: CA]"));
}
我们创建 City
对象并验证其 toString()
输出符合预期。更进一步,我们可以不检查完全相等,而是检查其他条件:
@Test
public void givenACity_whenHasToStringEqualToIgnoringCase_thenCorrect() {
City city = new City("San Francisco", "CA");
assertThat(city, hasToString(
equalToIgnoringCase("[NAME: SAN FRANCISCO, STATE: CA]")));
}
hasToString
支持两种重载形式:
- 直接传入字符串
- 传入文本匹配器(如
equalToIgnoringCase
)
因此我们还能这样用:
@Test
public void givenACity_whenHasToStringEmptyOrNullString_thenCorrect() {
City city = new City(null, null);
assertThat(city, hasToString(emptyOrNullString()));
}
更多文本匹配器用法可参考:Hamcrest 文本匹配器。接下来看下一个对象匹配器。
3.2. typeCompatibleWith
这个匹配器用于验证 is-a
继承关系。现在轮到我们的 Location
父类登场了:
@Test
public void givenACity_whenTypeCompatibleWithLocation_thenCorrect() {
City city = new City("San Francisco", "CA");
assertThat(city.getClass(), is(typeCompatibleWith(Location.class)));
}
断言 City
是 Location
的子类,显然成立。如果要验证非继承关系:
@Test
public void givenACity_whenTypeNotCompatibleWithString_thenCorrect() {
City city = new City("San Francisco", "CA");
assertThat(city.getClass(), is(not(typeCompatibleWith(String.class))));
}
City
当然不是 String
的子类。⚠️ 注意:所有 Java 对象都应通过以下测试:
@Test
public void givenACity_whenTypeCompatibleWithObject_thenCorrect() {
City city = new City("San Francisco", "CA");
assertThat(city.getClass(), is(typeCompatibleWith(Object.class)));
}
is
匹配器本质是包装其他匹配器,目的是让断言语义更清晰。
4. 总结
Hamcrest 提供了简洁优雅的断言方式。丰富的匹配器库既能提升开发效率,又能增强代码可读性。
对象匹配器是校验类属性的利器,简单直接不踩坑。
完整实现代码请查阅 GitHub 项目。