Cho ví dụ sau (sử dụng JUnit với bộ so khớp Hamcrest):
Map<String, Class<? extends Serializable>> expected = null;
Map<String, Class<java.util.Date>> result = null;
assertThat(result, is(expected));
Điều này không biên dịch với assertThat
chữ ký phương thức JUnit của:
public static <T> void assertThat(T actual, Matcher<T> matcher)
Thông báo lỗi trình biên dịch là:
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>>>)
Tuy nhiên, nếu tôi thay đổi assertThat
chữ ký phương thức thành:
public static <T> void assertThat(T result, Matcher<? extends T> matcher)
Sau đó, công việc biên dịch.
Vì vậy, ba câu hỏi:
- Tại sao chính xác không biên dịch phiên bản hiện tại? Mặc dù tôi mơ hồ hiểu các vấn đề hiệp phương sai ở đây, tôi chắc chắn không thể giải thích nó nếu tôi phải làm.
- Có bất kỳ nhược điểm trong việc thay đổi
assertThat
phương pháp thànhMatcher<? extends T>
? Có trường hợp nào khác sẽ phá vỡ nếu bạn làm điều đó? - Có bất kỳ điểm nào để khái quát hóa
assertThat
phương thức trong JUnit không? CácMatcher
lớp học dường như không cần đến nó, kể từ JUnit gọi phương thức trận đấu, mà không gõ với bất kỳ vẻ chung chung, và cũng giống như một nỗ lực để buộc một an toàn loại mà không làm gì cả, nhưMatcher
sẽ chỉ là không thực tế phù hợp, và thử nghiệm sẽ thất bại bất kể. Không có hoạt động không an toàn liên quan (hoặc có vẻ như vậy).
Để tham khảo, đây là triển khai JUnit của 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());
}
}