2014-04-16 111 views
3

我想確保使用特定的一組字符串作爲參數調用mocked。 例如,我有以下代碼:Mockito驗證方法是使用set調用的,它包含特定值

public class SomeLogic { 
    @Autowired 
    private SpecificService specificService; 

    public void action() { 
     Set<String> args = fillArgsMethod(); 
     specificService.handleArgs(args); 
    } 
} 

而且我目前的嘗試測試它下面

@Mock 
private SpecificService specificService 
@InjectMocks 
private SomeLogic someLogic; 

@Test 
public void testAction() { 
    someLogic.action(); 
    verify(specificService).handleArgs(anySet()); 
} 

但我想可以肯定,那handleArgs()將收到確切的集我期望的字符串。我如何修改驗證以檢查handleArgs是否被設置爲「first」,「second」? 感謝

回答

7

調用的測試方法

@Test 
    public void testAction() { 
     Set<String> expectedParams = new HashSet(Arrays.asList("first", "second"); 
     //call tested method 
     verify(specificService).handleArgs(expectedParams); 
    } 
+0

謝謝,我想我需要Hamcrest方法,但解決的辦法似乎更simplier – me1111

+0

不客氣。我使用Hamcrest是因爲它在測試失敗時具有更好的匹配和更好的報告。 – isah

10

Isah了一個有效的答案之前,準備好你的Set參數,但我想將注意力轉向的Mockito的更一般的功能,它是ArgumentCaptor

在你如果你會做大意如下的內容:

Class<HashSet<String>> setClass = (Class<HashSet<String>>)(Class)HashSet.class; 
ArgumentCaptor<Set<String>> setCaptor= ArgumentCaptor.forClass(setClass .class); 

verify(specificService).create(setCaptor.capture()); 
HashSet<String> capturedSet = setCaptor.getValue(); 

//do whatever test you want with capturedSet 
+1

在這種情況下,它可能是矯枉過正,但你得到了這是一個更一般的解決方案的一般想法:) – geoand

6

isah的解決方案是完美的對於你來說,如果你想確認這個集合恰好包含你指定的兩個項目; Mockito默認使用.equals進行比較,而Set.equals被定義爲以任意順序引用相同元素。

對於更靈活的「包含」符合您的問題的標題,它允許成員集超出你的預期值的測試,你也可以使用the Hamcrest contains matcher

someLogic.action(); 
verify(specificService).handleArgs(argThat(contains("first", "second"))); 

至少,這是怎麼回事應該看。不幸的是,argThat從Matcher推斷它的返回類型,它從參數中推斷它的返回類型,所以Java假定你的第一個參數不是Set<String>而是Iterable<capture#1-of ? extends String>。你需要顯式轉換和抑制警告得到它的工作:

// requires @SuppressWarnings("unchecked") 
verify(specificService).handleArgs(
    (Set<String>) argThat(contains("first", "second"))); 
相關問題