2014-04-16 110 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"))); 
相关问题