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

如何在JUnit中测试方法抛出的异常及异常消息?

嘿,这个问题我太熟悉了!测试方法抛出的异常,还要验证异常携带的消息?不同的Java测试框架都有对应的便捷玩法,我给你梳理几种最常用的方案:

1. 使用JUnit 5(JUnit Jupiter)

这是目前最推荐的版本,用assertThrows方法就能一站式搞定异常捕获和验证:

import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;

@Test
void testMyMethodThrowsExpectedException() {
    // 初始化被测类实例
    MyClass myInstance = new MyClass();
    
    // 执行方法并捕获指定类型的异常
    IllegalArgumentException thrown = assertThrows(
        IllegalArgumentException.class, // 预期的异常类型
        () -> myInstance.myMethod("invalidInput"), // 要测试的方法调用
        "myMethod应该在输入无效时抛出IllegalArgumentException" // 测试失败时的提示信息
    );
    
    // 验证异常消息是否符合预期
    assertEquals("输入参数不符合要求,请检查后重试", thrown.getMessage());
}

assertThrows会自动检查方法是否抛出了指定类型的异常,如果没抛出或者类型不对,测试直接失败。拿到异常对象后,还能灵活验证它的消息、堆栈等细节。

2. 使用JUnit 4

如果你还在维护JUnit 4的老项目,有两种方式:

  • 只验证异常类型:直接给@Test加expected属性
import org.junit.Test;

@Test(expected = NullPointerException.class)
void testMyMethodThrowsNPE() {
    MyClass myInstance = new MyClass();
    myInstance.myMethod(null); // 传入会触发NPE的参数
}
  • 要验证异常消息:用ExpectedException规则,灵活性更高
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

public class MyClassTest {
    @Rule
    public ExpectedException exceptionRule = ExpectedException.none();
    
    @Test
    void testMyMethodExceptionMessageMatches() {
        MyClass myInstance = new MyClass();
        
        // 先指定预期的异常类型
        exceptionRule.expect(IllegalArgumentException.class);
        // 再指定预期的异常消息(支持正则匹配哦)
        exceptionRule.expectMessage("输入参数不符合要求");
        
        // 执行被测方法
        myInstance.myMethod("invalidInput");
    }
}
3. 使用TestNG

如果你的项目用TestNG,也有两种玩法:

  • 注解式快速验证:
import org.testng.annotations.Test;

@Test(
    expectedExceptions = IllegalArgumentException.class,
    expectedExceptionsMessageRegExp = "输入参数不符合要求.*" // 支持正则
)
void testMyMethodThrowsExceptionWithCorrectMessage() {
    MyClass myInstance = new MyClass();
    myInstance.myMethod("invalidInput");
}
  • 手动捕获验证(适合需要额外逻辑的场景):
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.fail;

@Test
void testMyMethodExceptionDetailsManually() {
    MyClass myInstance = new MyClass();
    try {
        myInstance.myMethod("invalidInput");
        // 如果走到这一步,说明没抛出预期异常,直接标记测试失败
        fail("Expected IllegalArgumentException was not thrown");
    } catch (IllegalArgumentException e) {
        // 验证异常消息
        assertEquals("输入参数不符合要求", e.getMessage());
        // 还能验证异常的其他属性,比如cause之类的
    }
}

最后给个小建议:尽量指定具体的异常类型,别直接用Exception.class,这样能确保测试的是你预期的场景,避免漏掉其他意外抛出的异常,让测试更精准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:20:16