You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mockito Argument Captor使用问题:仅验证指定参数的方法调用

解决Mockito中仅验证特定参数方法调用次数的问题

你的问题核心是混淆了方法总调用次数和特定参数的方法调用次数,原代码里的verify(action, times(1)).perform(captor.capture())是在验证perform方法总共被调用1次,但实际你调用了2次(Pear和Apple各一次),所以才会触发TooManyActualInvocations错误。下面针对你的需求(仅验证perform(Pear.class)被调用1次,忽略Apple的调用次数)给出适配Mockito 1.10的解决方案:

方案1:仅验证调用次数(无需捕获参数)

这是最直接的方案,使用Mockito内置的isA()参数匹配器,精准匹配Pear类型的参数,让verify只统计符合该类型的调用次数:

@Test
public void simpleTest() {
    Action action = mock(Action.class);
    action.perform(new Pear());
    action.perform(new Apple());
    
    // 仅验证传入Pear实例的perform调用次数为1次
    verify(action, times(1)).perform(isA(Pear.class));
}

这个方案完全贴合你的业务场景(类似确保save(MyDomainObject)被调用一次),不需要关心其他参数的调用次数,也不会受未知调用次数的影响。

方案2:需要捕获Pear参数做进一步断言

如果你需要获取传入的Pear实例,验证其属性或状态,可以结合ArgumentCaptor和过滤逻辑实现:

@Test
public void simpleTest() {
    ArgumentCaptor<IFruit> captor = ArgumentCaptor.forClass(IFruit.class);
    Action action = mock(Action.class);
    action.perform(new Pear());
    action.perform(new Apple());
    
    // 捕获所有perform方法的调用参数(兼容任意次数的调用)
    verify(action, atLeast(0)).perform(captor.capture());
    
    // 筛选出Pear类型的参数并统计调用次数
    long pearInvocationCount = captor.getAllValues().stream()
        .filter(fruit -> fruit instanceof Pear)
        .count();
    
    // 断言Pear参数的调用次数为1次
    assertEquals(1, pearInvocationCount);
    
    // 可选:获取捕获的Pear实例做属性验证
    Pear capturedPear = (Pear) captor.getAllValues().stream()
        .filter(fruit -> fruit instanceof Pear)
        .findFirst()
        .orElse(null);
    // 比如验证Pear的属性:assertEquals("green", capturedPear.getColor());
}

这里用atLeast(0)是为了兼容Apple参数的调用次数(0次或多次),避免因为总调用次数不符合预期而报错,只聚焦你关心的Pear参数调用。

扩展:自定义参数匹配器(精准匹配属性)

如果需要更精细的匹配(比如不仅是类型,还要验证参数的特定属性),可以自定义ArgumentMatcher:

static class PearMatcher extends ArgumentMatcher<IFruit> {
    @Override
    public boolean matches(Object argument) {
        if (!(argument instanceof Pear)) {
            return false;
        }
        // 可以扩展属性验证,比如:
        // Pear pear = (Pear) argument;
        // return "green".equals(pear.getColor());
        return true;
    }
}

然后在verify中使用自定义匹配器:

verify(action, times(1)).perform(argThat(new PearMatcher()));

内容的提问来源于stack exchange,提问作者Bogdan Samondros

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:46:32