【发布时间】:2017-07-20 20:01:12
【问题描述】:
问题
假设以下简单测试:
@Test
public void test() throws Exception {
Object value = 1;
assertThat(value, greaterThan(0));
}
测试无法编译,因为“greaterThan”只能应用于Comparable 类型的实例。但我想断言value 是一个大于零的整数。我如何使用 Hamcrest 来表达这一点?
到目前为止我尝试了什么:
简单的解决方案是通过像这样强制转换匹配器来删除泛型:
assertThat(value, (Matcher)greaterThan(0));
可能,但会生成编译器警告并感觉不对。
一个冗长的替代方案是:
@Test
public void testName() throws Exception {
Object value = 1;
assertThat(value, instanceOfAnd(Integer.class, greaterThan(0)));
}
private static<T> Matcher<Object> instanceOfAnd(final Class<T> clazz, final Matcher<? extends T> submatcher) {
return new BaseMatcher<Object>() {
@Override
public boolean matches(final Object item) {
return clazz.isInstance(item) && submatcher.matches(clazz.cast(item));
}
@Override
public void describeTo(final Description description) {
description
.appendText("is instanceof ")
.appendValue(clazz)
.appendText(" and ")
.appendDescriptionOf(submatcher);
}
@Override
public void describeMismatch(final Object item, final Description description) {
if (clazz.isInstance(item)) {
submatcher.describeMismatch(item, description);
} else {
description
.appendText("instanceof ")
.appendValue(item == null ? null : item.getClass());
}
}
};
}
感觉“整洁”和“正确”,但对于看似简单的事情来说,这确实是很多代码。我试图在 hamcrest 中找到类似的内置内容,但没有成功,但也许我错过了什么?
背景
在我的实际测试用例中,代码是这样的:
Map<String, Object> map = executeMethodUnderTest();
assertThat(map, hasEntry(equalTo("the number"), greaterThan(0)));
在我简化的问题中,我也可以写assertThat((Integer)value, greaterThan(0))。在我的实际情况中,我可以写assertThat((Integer)map.get("the number"), greaterThan(0)));,但如果出现问题,这当然会使错误消息恶化。
【问题讨论】: