Mockito验证方法是用包含特定值的集合调用的



我想确保mocked是用一组特定的字符串作为参数调用的。例如,我有以下代码:

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()将接收到我所期望的确切的字符串集。如何修改验证以检查是否使用集合"first"、"second"调用handleArgs?感谢

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

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

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

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

为了进行更灵活的"包含"测试,以匹配您的问题标题,允许集合成员超出您的预期值,您还可以使用Hamcrest contains matcher:

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

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

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

相关内容

  • 没有找到相关文章

最新更新