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

如何验证被测代码中捕获的由Mock对象抛出的异常?

如何验证Mockito模拟的异常被主代码捕获?

在Java/Junit/Mockito环境中,模拟异常(比如doThrow())或验证未被捕获的异常(比如assertThrows())都很简单。但如果用doThrow()成功模拟了异常,而主代码把这个异常捕获了(比如空catch块),怎么确认这个异常确实被抛出过?

示例代码

业务代码

public void doFullOperation() {
    try {
        optionalService.blink();
    } catch (IOException exception) {
        // 无任何处理逻辑
    }
}

测试代码(待补充验证逻辑)

doThrow(IOException.class).when(mockOptionalService).blink();

classUnderTest.doFullOperation();

// ???如何确认IOException确实被抛出过?

解决方案

1. 验证模拟方法的调用(间接确认)

因为doThrow()是绑定到模拟对象的方法调用上的,只要mockOptionalService.blink()被调用,就一定会抛出我们定义的IOException。所以通过验证方法的调用次数,就能间接确认异常被触发:

doThrow(IOException.class).when(mockOptionalService).blink();

classUnderTest.doFullOperation();

// 验证blink方法被调用过一次
verify(mockOptionalService, times(1)).blink();

逻辑:如果方法没被调用,异常不会抛出;一旦调用,必然触发异常,而主代码的catch块会捕获它,测试不会报错。

2. 自定义Answer记录异常触发状态(直接确认)

通过自定义Answer,在抛出异常的同时标记一个状态变量,事后验证这个变量来直接确认异常被抛出:

AtomicBoolean exceptionThrown = new AtomicBoolean(false);

doAnswer(invocation -> {
    exceptionThrown.set(true);
    throw new IOException();
}).when(mockOptionalService).blink();

classUnderTest.doFullOperation();

// 断言异常确实被触发
assertTrue(exceptionThrown.get());

这种方式更直接,适合需要明确证明异常被抛出的场景。

3. 改造业务代码添加可观测行为(推荐)

如果允许修改业务代码,最好给catch块添加可观测的行为(比如日志),然后通过验证日志来确认异常被捕获:

修改后的业务代码
private static final Logger logger = LoggerFactory.getLogger(YourClass.class);

public void doFullOperation() {
    try {
        optionalService.blink();
    } catch (IOException exception) {
        logger.debug("捕获到IOException", exception);
    }
}
对应的测试代码(以slf4j-test为例)
// 获取业务类的日志记录器
Logger logger = LoggerFactory.getLogger(YourClass.class);
LoggingEventRecorder recorder = ((RecordingLogger) logger).getRecorder();

doThrow(IOException.class).when(mockOptionalService).blink();

classUnderTest.doFullOperation();

// 验证日志中存在对应的异常捕获记录
assertTrue(recorder.hasRecordMatching(
    level -> level == Level.DEBUG,
    msg -> msg.contains("捕获到IOException")
));

这种方式更贴合实际业务逻辑,同时能清晰验证异常的捕获流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 11:56:30