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
相关产品推荐
相关产品推荐

