如何在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
相关产品推荐
相关产品推荐

