Spring Boot+Eclipse环境下Mockito测试抛异常的void方法失败如何解决?
问题排查
你的测试失败是因为测试代码存在3处核心逻辑错误,和异常类实现无关:
- 待测试的
UserServiceImpl错误使用@Mock注解:@Mock会生成完全伪造的对象,不会执行任何真实业务代码,你当前的写法相当于直接伪造了Service方法的抛异常行为,完全没有验证deleteUserById的真实逻辑。 - 缺少异常预期声明:JUnit 5执行测试时如果捕获到未声明预期的异常,会直接判定测试失败,你需要主动声明期望抛出
ResourceNotFoundException。 - 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
相关产品推荐
相关产品推荐

