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

AssertJ如何结合异常捕获与方法返回值断言?

问题描述

我有一个方法,在处理JSON文件时会捕获IOException,当该异常发生时,会将异常信息写入数据库并返回false;正常处理完成则返回true,代码示例如下:

public boolean method(){ 
    try{ 
        // process json file 
        return true; 
    } catch (IOException e) { 
        // write stuff into db 
        return false; 
    } 
}

我希望在单元测试中同时断言该异常的实例/消息以及方法的返回值。尝试使用Assertions.assertThatThrownBy(() -> objectUnderTest.method()).isInstanceOf(IOException.class)时,出现错误:java.lang.AssertionError: Expecting code to raise a throwable.,而使用Assertions.assertThat(objectUnderTest.method()).isFalse()可正常断言返回值。请问如何实现两者的结合断言?

解决方案

核心问题在于你的方法内部已经捕获了IOException,不会将异常抛出到方法外部,所以assertThatThrownBy自然捕获不到异常。要同时断言异常细节和方法返回值,可通过以下几种方式实现:

1. 拆分方法逻辑(推荐)

把JSON处理的核心逻辑和异常捕获/状态返回逻辑拆分,让核心方法抛出异常,对外方法负责处理异常并返回状态:

// 核心JSON处理方法,不捕获异常
private void processJsonFile() throws IOException {
    // 原有的JSON处理代码
}

// 对外暴露的业务方法
public boolean method(){ 
    try{ 
        processJsonFile();
        return true; 
    } catch (IOException e) { 
        // 将异常信息写入数据库
        return false; 
    } 
}

单元测试时分开验证:

// 验证核心方法的异常场景
Assertions.assertThatThrownBy(() -> objectUnderTest.processJsonFile())
          .isInstanceOf(IOException.class)
          .hasMessageContaining("目标异常消息关键词");

// 验证业务方法的返回值
Assertions.assertThat(objectUnderTest.method()).isFalse();

2. 利用Mock框架拦截异常(无需重构)

如果不想改动原有代码,可以用Mockito这类Mock框架模拟依赖组件抛出异常,同时验证方法返回值:

@Mock
private FileReader fileReader; // 假设JSON处理依赖该组件

@InjectMocks
private YourClass objectUnderTest;

@Test
void testMethodWithIOException() throws Exception {
    // 模拟依赖组件抛出IOException
    doThrow(new IOException("测试异常消息")).when(fileReader).read();
    
    // 调用方法并断言返回值
    boolean result = objectUnderTest.method();
    Assertions.assertThat(result).isFalse();
    
    // 可通过验证Mock交互确认异常触发逻辑,若需直接获取异常实例,可结合PowerMock等工具拦截内部捕获的异常
}

3. 添加异常记录变量

在类内部添加成员变量存储捕获到的异常,提供获取方法:

public class YourClass {
    private IOException caughtException;

    public boolean method(){ 
        caughtException = null;
        try{ 
            // process json file 
            return true; 
        } catch (IOException e) { 
            caughtException = e;
            // 将异常信息写入数据库
            return false; 
        } 
    }

    public IOException getCaughtException() {
        return caughtException;
    }
}

单元测试时同时验证返回值和异常:

@Test
void testMethodWithIOException() {
    boolean result = objectUnderTest.method();
    Assertions.assertThat(result).isFalse();
    Assertions.assertThat(objectUnderTest.getCaughtException())
              .isInstanceOf(IOException.class)
              .hasMessage("预期的异常内容");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 08:52:25