2015-09-25 44 views
4

我試圖理解爲什麼這個JUnit的說法是給我一個編譯時錯誤測試地圖時:使用通用界通配符使用JUnit

Map<String, Set<String>> actual = methodToTest(); 
assertThat(result, hasEntry("foo", new HashSet<String>(Arrays.asList("bar")))); 

如果我這樣寫它工作正常:

Map<String, Set<String>> actual = methodToTest(); 
Set<String> expected = new HashSet<String>(Arrays.asList("bar")); 
assertThat(result, hasEntry("foo", expected)); 

從第一實施例中的編譯器的錯誤是:

The method assertThat(T, Matcher<? super T>) in the type Assert is not 
applicable for the arguments (Map<String,Set<String>>, Matcher<Map<? 
extends String,? extends HashSet<String>>>) 

HashSet<String>是亞型Set<String>那麼爲什麼這不工作?

+0

它可以在java8中工作嗎? – ZhongYu

+0

不知道這是在java 7中嘗試的。 – acvcu

+0

[「通配符地獄」](http://bayou.io/draft/Capturing_Wildcards.html#Wildcard_Hell):)只是拋棄了這個問題... – ZhongYu

回答

4

HashSet<String>Set<String>爲真的子類型。

但是,Matcher<Map<String,HashSet<String>>>而不是Matcher<Map<String,Set<String>>>的子集。請記住,List<String>不是List<Object>的子類型。

assertThat方法預計類型爲Matcher<? super Map<String, Set<String>>>的參數與Matcher<Map<String,HashSet<String>>>不兼容。

+1

'hasEntry()'簽名可能設計錯誤。 – ZhongYu