如何用Mockito测试自定义异常?我的认证服务测试异常未触发
问题分析与修复方案
你的测试代码核心问题是错误地Mock了被测试类AuthenService的authenticate方法,而不是去配置它的依赖UserRepo的行为。Mockito的正确用法是Mock被测试类的依赖组件,而非被测试类本身。
错误原因
你当前的测试代码直接指定when(as.authenticate(...))抛出异常,这相当于绕过了AuthenService的真实逻辑,完全起不到测试作用。正确的做法是通过MockUserRepo的方法返回值,来驱动AuthenService的真实逻辑执行,进而验证结果是否符合预期。
修复后的测试代码
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class AuthenServiceTest { AuthenService as; UserRepo ur; @BeforeEach public void init() { ur = mock(UserRepo.class); as = new AuthenService(ur); } @Test public void authenticate_InvalidCredentials_ThrowsUserNotFoundException() { // 配置UserRepo的validate方法,当传入"abc"和"123"时返回false when(ur.validate("abc", "123")).thenReturn(false); // 调用被测试方法,并验证是否抛出预期异常 assertThrows(UserNotFoundException.class, () -> { as.authenticate("abc", "123"); }); } }
补充:成功场景的测试示例
为了覆盖更多逻辑,你还可以添加成功登录的测试:
import static org.junit.jupiter.api.Assertions.assertEquals; @Test public void authenticate_ValidCredentials_ReturnsUser() throws UserNotFoundException { // 构造测试用的User对象 User testUser = new User("abc", "123"); // 配置UserRepo的行为 when(ur.validate("abc", "123")).thenReturn(true); when(ur.findUsername("abc")).thenReturn(testUser); // 调用方法并验证返回结果 User result = as.authenticate("abc", "123"); assertEquals(testUser, result); }
关键要点
- 永远只Mock被测试类的依赖组件(比如这里的
UserRepo),不要Mock被测试类本身。 - 通过配置Mock对象的方法返回值,来控制被测试类的执行路径。
- 使用
assertThrows来验证方法是否抛出预期异常,这是JUnit 5的标准用法。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

