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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 00:35:15