2013-09-04 24 views
6

Các khớp IsIterableContainingInAnyOrder có hai quá tải đối với phương pháp nhà máy tĩnh containsInAnyOrder (cả hai đều có kiểu trả về Matcher<java.lang.Iterable<? extends T>>):quá tải xung đột với nhau cho hamcrest Matcher

  1. containsInAnyOrder(java.util.Collection<Matcher<? super T>> itemMatchers)
  2. containsInAnyOrder(Matcher<? super T>... itemMatchers)

Bây giờ xem xét sau đây chương trình:

import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder; 
import static org.hamcrest.core.IsEqual.equalTo; 
import static org.junit.Assert.assertThat; 

import java.util.Arrays; 

import org.junit.Test; 

public class SomeTest { 

    @SuppressWarnings("unchecked") 
    @Test 
    public void foo() { 
     assertThat(Arrays.asList("foo","bar"), 
         containsInAnyOrder(equalTo("foo"), equalTo("bar"))); 
    } 

} 

Khi thực hiện điều này như là một thử nghiệm JUnit, nó vượt qua, như mong đợi. Nó sử dụng quá tải thứ hai của containsInAnyOrder được hiển thị ở trên.

Bây giờ, khi tôi thay đổi sự khẳng định này (mà chính xác phù hợp với ví dụ được đưa ra trong documentation of the first overload):

assertThat(Arrays.asList("foo","bar"), 
      containsInAnyOrder(Arrays.asList(equalTo("foo"), equalTo("bar")))); 
           ^^^^^^^^^^^^^^ 

nó không biên dịch nữa, vì bây giờ các trình biên dịch suy luận kiểu trả về của containsInAnyOrder để là

Matcher<Iterable<? extends List<Matcher<String>>>> 

Dường như trình biên dịch vẫn chọn quá tải thứ hai. Nếu nó được sử dụng đầu tiên, ví dụ sẽ hoạt động. Tại sao nó cư xử như thế này? Làm thế nào tôi có thể thực hiện công việc này?

Tôi đang sử dụng Hamcrest 1.3 và Oracle Java 1.7.

Trả lời

4

Nó thực sự phù hợp với cả hai phương pháp quá tải. Tôi không chắc tại sao chính xác người đầu tiên được chọn, nhưng bạn có thể cung cấp một gợi ý để làm cho nó chọn phương pháp đúng.

By đúc lập luận để Collection:

assertThat(Arrays.asList("foo","bar"), 
     containsInAnyOrder((Collection)Arrays.asList(equalTo("foo"), equalTo("bar")))); 

hoặc bằng cách xác định loại T generic như <String> (không làm việc với nhập khẩu tĩnh, mặc dù):

assertThat(Arrays.asList("foo","bar"), 
     IsIterableContainingInAnyOrder.<String>containsInAnyOrder(Arrays.asList(equalTo("foo"), equalTo("bar")))); 
+0

Tôi khuyên bạn nên phiên bản thứ hai cho loại an toàn.Ngoài ra bạn có thể viết 'Matchers. containsInAnyOrder' thay vì 'IsIterableContainingInAnyOrder. containsInAnyOrder'. – eee

2

này thậm chí còn một hơi khó hơn khi bạn kết hợp các đối tượng của riêng bạn, thay vì các chuỗi đơn giản, để có được các generics để làm việc ra ngoài. Nếu bạn đang sử dụng varargs containsInAnyOrder(Matcher<? super T>... itemMatchers) như trong ví dụ đầu tiên của câu hỏi, bạn sẽ nhận được một Tạo mảng Generics không được kiểm tra cho thông số chênh lệch. Ví dụ:

assertThat(myDTOList, 
    containsInAnyOrder(sameStateAs(expectedMyDTO1), sameStateAs(expectedMyDTO2)); 

Một cách để sau đó giải quyết vấn đề OP nêu trong câu hỏi, là để xác định bộ sưu tập các quẹt như sau:

Collection<Matcher<? super MyDTO>> expectedMyDTOs = 
    Arrays.<Matcher<? super MyDTO>>asList(sameStateAs(expectedMyDTO1), sameStateAs(expectedMyDTO2)); 

// Use like this: 
assertThat(myDTOList, 
    containsInAnyOrder(expectedMyDTOs); 
+0

wow, '? siêu MyDTO' đã làm các trick. '? siêu Object' không:) cảm ơn rất nhiều! – borowis

2

Với hamcrest 1.3 bạn có thể sử dụng Matchers lớp thay vì IsIterableContainingInAnyOrder trực tiếp như đã đề cập bởi @eee. Matchers thực sự chỉ gọi IsIterableContainingInAnyOrder cho bạn.

import static org.hamcrest.core.IsEqual.equalTo; 
import static org.junit.Assert.assertThat; 

import org.hamcrest.Matchers; 
import java.util.Arrays; 
import org.junit.Test; 

public class SomeTest 
{ 
    @Test 
    public void foo() { 
     assertThat(Arrays.asList("foo","bar"), 
      Matchers.<OrderValidationStep>containsInAnyOrder("foo", "bar")); 
    } 
} 

Lưu ý rằng bạn không thể sử dụng nhập khẩu tĩnh nếu bạn muốn Type cuộc gọi của bạn để containsInAnyOrder, và điều này loại bỏ sự cần thiết phải thêm @SuppressWarnings("unchecked")