给定以下示例(将JUnit与Hamcrest匹配器结合使用):
Map> expected = null;
Map> result = null;
assertThat(result, is(expected));
这不能与以下内容的JUnit assertThat方法签名一起编译:
public static void assertThat(T actual, Matcher matcher)
编译器错误消息是:
Error:Error:line (102)cannot find symbol method
assertThat(java.util.Map>,
org.hamcrest.Matcher
extends java.io.Serializable>>>)
但是,如果我将assertThat方法签名更改为:
public static void assertThat(T result, Matcher extends T> matcher)
然后编译工作。
所以三个问题:
为什么当前版本完全不编译?尽管我在这里模糊地理解了协方差问题,但如果需要的话,我当然无法解释。
将assertThat方法更改为有什么缺点Matcher extends T>吗?如果这样做,还有其他情况会中断吗?
assertThat在JUnit中通用化方法有什么意义吗?该Matcher级似乎并不需要它,因为JUnit的调用matches方法,它不与任何通用的,只是看起来像键入企图迫使一个类型安全这并不做任何事情,因为Matcher只会事实上并不匹配,则无论如何测试都将失败。不涉及任何不安全的操作(或看起来如此)。
供参考,以下是JUnit的实现assertThat:
public static void assertThat(T actual, Matcher matcher) {
assertThat("", actual, matcher);
}
public static void assertThat(String reason, T actual, Matcher matcher) {
if (!matcher.matches(actual)) {
Description description = new StringDescription();
description.appendText(reason);
description.appendText("\nExpected: ");
matcher.describeTo(description);
description
.appendText("\n got: ")
.appendValue(actual)
.appendText("\n");
throw new java.lang.AssertionError(description.toString());
}
}