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 assertThat
yö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, assertThat
yö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.
assertThat
Yöntemi değiştirmenin bir dezavantajı var mıMatcher<? extends T>
? Bunu yaparsanız kırılacak başka durumlar var mı?- JUnit'te
assertThat
yöntemin jenerikleştirilmesinin bir anlamı var mı ?Matcher
JUnit ş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üyorMatcher
aslı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());
}
}