使用Kotlin与Mockito编写catch块代码的单元测试方法
Mockito单元测试实现方案
前置说明
你提供的代码属于接口层响应逻辑,依赖payHandler(支付处理类)和exceptionHelper(异常处理工具类)两个实例,测试catch块的核心逻辑是:模拟payHandler调用方法时抛出异常,验证最终返回值是exceptionHelper构造的错误响应即可。
实现步骤
1. 测试环境准备
测试类需要引入Mockito依赖,同时声明三个对象:
- 待测试的业务类实例(示例中假设为
PayController) - mock出来的
PayHandler实例 - mock出来的
ExceptionHelper实例
2. 测试用例示例
Java版本(JUnit 5 + Mockito)
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; import static org.junit.jupiter.api.Assertions.*; @ExtendWith(MockitoExtension.class) public class PayControllerTest { // 注入mock依赖到待测试的业务类 @InjectMocks private PayController payController; @Mock private PayHandler payHandler; @Mock private ExceptionHelper exceptionHelper; @Test void getFees_shouldReturnErrorResponseWhenPayHandlerThrowException() { // 构造测试入参和预设返回值 PayRequestDTO body = new PayRequestDTO(); PayConfig config = new PayConfig(); RuntimeException testException = new RuntimeException("支付费用查询失败"); Response expectedErrorResp = Response.serverError().entity("查询失败").build(); // 打桩1:调用payHandler的查询方法时抛出预设异常 when(payHandler.getFeesForPay(any(PayRequestDTO.class), any(PayConfig.class))) .thenThrow(testException); // 打桩2:异常处理工具返回预设的错误响应 when(exceptionHelper.buildResponseFromException(any(RuntimeException.class))) .thenReturn(expectedErrorResp); // 执行待测试的业务方法 Response actualResp = payController.getPayFees(body, config); // 验证结果 assertEquals(expectedErrorResp, actualResp); // 验证payHandler的查询方法确实被调用了一次 verify(payHandler, times(1)).getFeesForPay(body, config); // 验证异常工具确实接收到了抛出的异常并被调用一次 verify(exceptionHelper, times(1)).buildResponseFromException(testException); } }
Kotlin版本(JUnit 5 + Mockito-Kotlin)
import org.junit.jupiter.api.Test import org.junit.jupiter.api.extension.ExtendWith import org.mockito.InjectMocks import org.mockito.Mock import org.mockito.junit.jupiter.MockitoExtension import org.mockito.kotlin.any import org.mockito.kotlin.whenever import org.mockito.kotlin.verify import kotlin.test.assertEquals @ExtendWith(MockitoExtension::class) class PayControllerTest { @InjectMocks lateinit var payController: PayController @Mock lateinit var payHandler: PayHandler @Mock lateinit var exceptionHelper: ExceptionHelper @Test fun `查询支付费用时payHandler抛异常 应返回异常工具构造的错误响应`() { // 构造测试数据 val body = PayRequestDTO() val config = PayConfig() val testException = RuntimeException("支付费用查询失败") val expectedErrorResp = Response.serverError().entity("查询失败").build() // 打桩 whenever(payHandler.getFeesForPay(any(), any())).thenThrow(testException) whenever(exceptionHelper.buildResponseFromException(any())).thenReturn(expectedErrorResp) // 执行方法 val actualResp = payController.getPayFees(body, config) // 验证结果 assertEquals(expectedErrorResp, actualResp) verify(payHandler).getFeesForPay(body, config) verify(exceptionHelper).buildResponseFromException(testException) } }
注意事项
- 如果需要严格匹配入参,可以把打桩逻辑里的
any()替换为实际构造的入参对象,避免匹配范围过大 - 如果
exceptionHelper是静态工具类,需要用Mockito inline模式或者PowerMock来mock静态方法,更推荐把工具类改成注入实例的写法,更易于单测编写 - 可以根据业务场景替换抛出的异常类型为自定义业务异常,测试逻辑会更贴合实际运行情况
内容的提问来源于stack exchange,提问作者user6190218
相关产品推荐
相关产品推荐

