2016-12-13 64 views
3

集合在一個測試類使用AssertJ,我也有類似的代碼如下:泛型和通配符在Java

public void someTest() { 
    assertThat(getNames()).has(sameNamesAs(getExpectedNames())); 
    assertThat(getNames()).doesNotHave(sameNamesAs(getOtherNames())); 
} 

private List<String> getNames() { 
    return null; 
} 
private List<String> getExpectedNames() { 
    return null; 
} 
private List<String> getOtherNames() { 
    return null; 
} 

private Condition<List<String>> sameNamesAs(List<String> rhs) { 
    return new Condition<List<String>>("same names as " + rhs) { 
     @Override 
     public boolean matches(final List<String> lhs) { 
      return lhs.containsAll(rhs) && rhs.containsAll(lhs); 
     } 
    }; 
} 

我上調用編譯錯誤hasdoesNotHave

has/doesNotHave 
(org.assertj.core.api.Condition<? super java.util.List<? extends java.lang.String>>) 
in AbstractListAssert cannot be applied 
to 
(org.assertj.core.api.Condition<java.util.List<java.lang.String>>). 

我是新來的Java和我不明白的問題:java.util.List是超級類型的java.util.Listjava.lang.String延伸java.lang.String,不是嗎?

回答

2

在你的情況下,hasdoesNotHave方法採取Condition<? super List<? extends T>條件,而不是作爲Condition<? super List<T>>你是從你的Condition<List<T>> sameNamesAs方法返回。

您需要Condition<List<? extends String>>類型的實例(它的原始類型Condition<? super List<? extends String>>的子類):

private Condition<List<? extends String>> sameNamesAs(List<String> rhs) { 
    return new Condition<List<? extends String>>("same names as " + rhs) { ... }; 
} 

我試圖說明這與下面的代碼片段:

List<String> list = getNames(); 

// ELEMENT = String, ACTUAL = List<? extends ELEMENT> 
ListAssert<String> assertThat = assertThat(list); 

// by the signature, we have to pass Condition<? super ELEMENT> or Condition<? super ACTUAL> 
// Condition<? super ACTUAL> = Condition<? super List<? extends String>> 
Condition<List<? extends String>> condition = sameNamesAs(list); 

// Condition<List<? extends String>> extends Condition<? super List<? extends String>> 
assertThat.has(condition); 
+0

謝謝你的解決方案和解釋。如果我理解正確,我的錯誤是相信'List '是一個超級類型的List <?擴展String>',而這兩個類型實際上沒有繼承關係。我只是不明白你的答案中的這一行:'//通過簽名,我們必須通過條件<?超級元素>或條件<?超實際>'。這裏的'ACTUAL'是什麼? –

+0

@ChristopheFuzier,是的,因爲'列表'是* List *的一個子*。擴展String>'。 'ACTUAL','ELEMENT'分別是方法和'Assertions'類的不同泛型參數('ACTUAL = List <?extends ELEMENT>') – Andrew