使用set调用Mockito验证方法,其中包含特定值

me1*_*111 5 verify mockito

我想确保使用特定的字符串集作为参数调用mocked.例如,我有以下代码:

public class SomeLogic {
    @Autowired
    private SpecificService specificService;

    public void action() {
        Set<String> args = fillArgsMethod();
        specificService.handleArgs(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

我目前尝试测试它是以下

@Mock
private SpecificService specificService
@InjectMocks
private SomeLogic someLogic;

@Test
public void testAction() {
    someLogic.action();
    verify(specificService).handleArgs(anySet());
}
Run Code Online (Sandbox Code Playgroud)

但我想确定,handleArgs()将收到我期望的确切字符串集.如何修改验证以检查是否使用set"first","second"调用handleArgs?谢谢

geo*_*and 11

Isah给出了一个有效的答案,但我想把你的注意力转向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
Run Code Online (Sandbox Code Playgroud)


isa*_*sah 8

Set在调用测试方法之前准备参数

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


Jef*_*ica 8

isah的解决方案非常适合您,如果您想确认该集合包含您指定的两个项目; Mockito .equals默认使用比较,并Set.equals定义为以任何顺序引用相等的元素.

对于与您的问题标题匹配的更灵活的"包含"测试,允许集合成员超出预期值,您还可以使用Hamcrest contains匹配器:

someLogic.action();
verify(specificService).handleArgs(argThat(contains("first", "second")));
Run Code Online (Sandbox Code Playgroud)

至少,它应该是这样的.不幸的是,argThat从Matcher中推断出它的返回类型,它从参数中推断出它的返回类型,因此Java假定你的第一个参数不是a Set<String>而是a Iterable<capture#1-of ? extends String>.您需要显式转换并禁止警告才能使其工作:

// requires @SuppressWarnings("unchecked")
verify(specificService).handleArgs(
    (Set<String>) argThat(contains("first", "second")));
Run Code Online (Sandbox Code Playgroud)