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

如何对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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 14:05:16