如何对catch异常语句进行单元测试?代码覆盖率未达标
如何测试catch语句以覆盖代码覆盖率?
你的业务代码里的catch块同时处理ClientException和InternalServerError两种异常,但当前测试只覆盖了InternalServerError的情况,漏掉了ClientException分支,这就是覆盖率未通过的原因。
业务代码
public Method execute(@NonNull final String test) throws ServiceException { try { object = javaClient.fetchInfo(test); } catch (ClientException | InternalServerError e) { throw serviceExceptionAdapter.apply(e); } return object; }
当前测试代码
@BeforeEach void setup() { this.serviceExceptionAdapter = mock(ExceptionAdapter.class); this.mockJavaClient = mock(JavaClient.class); proxy = new Proxy(mockJavaClient, serviceExceptionAdapter); } @Test void test_InternalServerError() { when(mockJavaClient.fetchInfo(any())).thenThrow(InternalServerError.class); when(serviceExceptionAdapter.apply(any())).thenThrow(ServiceException.class); assertThrows(ServiceException.class, () -> proxy.execute(test)); verify(serviceExceptionAdapter, times(1)).apply(any()); }
解决方法
1. 新增单独的ClientException测试
直接添加一个测试方法,模拟抛出ClientException的场景:
@Test void test_ClientException() { // 模拟JavaClient抛出ClientException when(mockJavaClient.fetchInfo(any())).thenThrow(ClientException.class); // 模拟适配器转换后抛出ServiceException when(serviceExceptionAdapter.apply(any())).thenThrow(ServiceException.class); // 验证执行方法会抛出ServiceException assertThrows(ServiceException.class, () -> proxy.execute(test)); // 验证适配器被调用一次 verify(serviceExceptionAdapter, times(1)).apply(any()); }
2. 使用参数化测试简化代码
如果想减少重复代码,可以用JUnit 5的参数化测试,一次性覆盖两种异常场景:
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; @ParameterizedTest @ValueSource(classes = {InternalServerError.class, ClientException.class}) void test_ExceptionHandling(Class<? extends Exception> exceptionClass) throws Exception { // 实例化对应的异常对象 Exception exception = exceptionClass.getDeclaredConstructor().newInstance(); when(mockJavaClient.fetchInfo(any())).thenThrow(exception); when(serviceExceptionAdapter.apply(any())).thenThrow(ServiceException.class); assertThrows(ServiceException.class, () -> proxy.execute(test)); verify(serviceExceptionAdapter, times(1)).apply(any()); }
这样就能完整覆盖catch块里的两个异常分支,通过代码覆盖率检测。
内容的提问来源于stack exchange,提问作者blacktuna
相关产品推荐
相关产品推荐

