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

使用Mockito模拟异常测试自定义Predicate失败,Mock类识别异常

问题

我编写了如下自定义Predicate,希望使用Mockito对其进行测试。由于目标异常类(ServiceUnavailable)没有公共构造方法,我对该异常类进行了Mock。但运行测试时断言失败,Predicate返回false而非true。打印Mock异常的类名显示为WebClientResponseException$ServiceUnavailable$MockitoMock$54675,看起来Mock未被正确识别。请问我哪里操作有误?

PredicateTest

@ExtendsWith(MockitoExtension.class)
class PredicateTest{

    @InjectMocks
    CustomPredicate customPredicate;

    @Test
    public void testPredicate(){
        final ServiceUnavailable serviceUnavailable = mock(ServiceUnavailable.class);
        assertTrue(customPredicate.test(serviceUnavailable));
    }  
}

CustomPredicate

class CustomPredicate implements Predicate<Throwable>{

    private static final List<Class<?>> EXCEPTIONS = Arrays.asList(WebClientResponseException.ServiceUnavailable.class);

    private static final Predicate<? super Throwable> CLASS_TO_CONTROL = throwable -> EXCEPTIONS.contains(throwable.getClass());

    @Override
    public boolean test(Throwable t){
        return ExceptionUtils.getThrowableList(t).stream().anyMatch(CLASS_TO_CONTROL);
    }
}
解决方案

问题出在Mockito生成的Mock对象是原类的动态子类,所以throwable.getClass()返回的是类似WebClientResponseException$ServiceUnavailable$MockitoMock$xxxx的子类,而不是你在EXCEPTIONS列表中存放的WebClientResponseException.ServiceUnavailable.class,自然匹配失败。

修复方法有两种:

  • 改用Class.isAssignableFrom()判断类型兼容性
    把CLASS_TO_CONTROL的判断逻辑改成检查异常类是否是目标类的子类或本身:

    private static final Predicate<? super Throwable> CLASS_TO_CONTROL = 
        throwable -> EXCEPTIONS.stream().anyMatch(clazz -> clazz.isAssignableFrom(throwable.getClass()));
    

    这样不管是原类对象还是Mockito生成的子类Mock对象,都能被正确识别。

  • 使用反射创建原异常实例(如果可行)
    如果不想修改Predicate逻辑,可以尝试通过反射调用ServiceUnavailable的私有构造方法创建真实实例,而不是Mock:

    @Test
    public void testPredicate() throws Exception {
        Constructor<WebClientResponseException.ServiceUnavailable> constructor = 
            WebClientResponseException.ServiceUnavailable.class.getDeclaredConstructor(int.class, String.class, HttpHeaders.class, byte[].class, Charset.class);
        constructor.setAccessible(true);
        WebClientResponseException.ServiceUnavailable serviceUnavailable = 
            constructor.newInstance(503, "Service Unavailable", HttpHeaders.EMPTY, new byte[0], StandardCharsets.UTF_8);
        
        assertTrue(customPredicate.test(serviceUnavailable));
    }
    

    这种方式能拿到真实的异常类实例,匹配逻辑不需要修改,但依赖反射,需要注意构造方法参数是否正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 14:05:22