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

Spring Boot+Eclipse环境下Mockito测试抛异常的void方法失败如何解决?

问题排查

你的测试失败是因为测试代码存在3处核心逻辑错误,和异常类实现无关:

  1. 待测试的UserServiceImpl错误使用@Mock注解:@Mock会生成完全伪造的对象,不会执行任何真实业务代码,你当前的写法相当于直接伪造了Service方法的抛异常行为,完全没有验证deleteUserById的真实逻辑。
  2. 缺少异常预期声明:JUnit 5执行测试时如果捕获到未声明预期的异常,会直接判定测试失败,你需要主动声明期望抛出ResourceNotFoundException。
  3. Mock对象错误:你需要模拟的是依赖UserRepository的findById返回空值,以此触发Service层的异常抛出逻辑,而非模拟Service本身的方法。
修复后的测试代码
import org.junit.jupiter.api.DisplayName;
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.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.when;
import java.util.Optional;
import succeed.app.start.exception.ResourceNotFoundException;
import succeed.app.start.repository.UserRepository;

@ExtendWith(MockitoExtension.class)
public class UserServiceImplTest {
    
    @Mock
    UserRepository userRepository;
    
    // 改用@InjectMocks创建真实的Service实例,自动注入mock的Repository
    @InjectMocks
    UserServiceImpl userService;
    
    @Test
    @DisplayName("用户不存在时应抛出ResourceNotFoundException")
    void shouldThrowResourceNotFoundExceptionWhenUserNotExists() {
        final long nonExistingId = 12902450235L;
        // 模拟Repository查询返回空
        when(userRepository.findById(nonExistingId)).thenReturn(Optional.empty());
        
        // 声明预期异常,执行方法并验证异常类型
        assertThrows(ResourceNotFoundException.class, () -> userService.deleteUserById(nonExistingId));
    }
}
补充说明

Spring Boot环境下测试void方法抛异常的通用逻辑:

  • 待测试的业务类使用@InjectMocks注解,保证执行业务真实逻辑,依赖的外部组件(DAO、外部接口客户端等)使用@Mock注解模拟返回值。
  • JUnit 5统一使用assertThrows方法声明预期异常,第一个参数为期望抛出的异常类,第二个参数为待执行的方法逻辑,方法返回值为抛出的异常实例,你还可以进一步校验异常的消息、属性是否符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 15:42:00