Aşağıdaki örnek göz önüne alındığında (Hamcrest eşleştiricileri ile JUnit kullanımı):
Map<String, Class<? extends Serializable>> expected = null;
Map<String, Class<java.util.Date>> result = null;
assertThat(result, is(expected));
Bu, JUnit assertThatyönteminin imzasıyla derlenmez :
public static <T> void assertThat(T actual, Matcher<T> matcher)
Derleyici hata mesajı:
Error:Error:line (102)cannot find symbol method
assertThat(java.util.Map<java.lang.String,java.lang.Class<java.util.Date>>,
org.hamcrest.Matcher<java.util.Map<java.lang.String,java.lang.Class
<? extends java.io.Serializable>>>)
Ancak, assertThatyöntem imzasını şu şekilde değiştirirsem:
public static <T> void assertThat(T result, Matcher<? extends T> matcher)
Sonra derleme çalışır.
Üç soru var:
- Mevcut sürüm neden tam olarak derlenmiyor? Her ne kadar buradaki kovaryans konularını belirsiz bir şekilde anlasam da, yapmam gerekirse kesinlikle açıklayamadım.
assertThatYöntemi değiştirmenin bir dezavantajı var mıMatcher<? extends T>? Bunu yaparsanız kırılacak başka durumlar var mı?- JUnit'te
assertThatyöntemin jenerikleştirilmesinin bir anlamı var mı ?MatcherJUnit şey yapmaz bir tür güvenliği zorlamak için bir girişim gibi herhangi jenerik ve sadece bakışlarla yazılmadı maçlar yöntemini çağırır beri olduğu gibi sınıf, bunu gerektirir görünmüyorMatcheraslında sadece olmaz ve test ne olursa olsun başarısız olur. Güvenli olmayan operasyonlar söz konusu değil (ya da öyle görünüyor).
Referans olarak, JUnit uygulaması şöyledir assertThat:
public static <T> void assertThat(T actual, Matcher<T> matcher) {
assertThat("", actual, matcher);
}
public static <T> void assertThat(String reason, T actual, Matcher<T> 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());
}
}