本文目录导读:

在JUnit 5中,测试异常(Assertions for Exceptions)主要通过 org.junit.jupiter.api.Assertions 类中的 assertThrows 和 assertDoesNotThrow 方法来实现。
assertThrows - 断言抛出指定异常
assertThrows 是最常用的异常断言方法,它会验证被测试代码是否抛出了指定类型的异常。
基本用法
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertThrows;
public class ExceptionTest {
@Test
void testThrowException() {
// assertThrows(异常类型, 可执行代码)
assertThrows(IllegalArgumentException.class, () -> {
// 这里应该抛出IllegalArgumentException的代码
throw new IllegalArgumentException("参数错误");
});
}
}
获取异常对象进行进一步断言
assertThrows 会返回捕获到的异常对象,可以用来进行更具体的验证:
@Test
void testExceptionMessage() {
// 获取异常对象
IllegalArgumentException exception = assertThrows(
IllegalArgumentException.class,
() -> {
throw new IllegalArgumentException("参数不能为负数");
}
);
// 验证异常消息
assertEquals("参数不能为负数", exception.getMessage());
// 验证异常的cause
assertNull(exception.getCause());
}
实际业务场景示例
public class Calculator {
public int divide(int a, int b) {
if (b == 0) {
throw new ArithmeticException("除数不能为0");
}
return a / b;
}
public void validateAge(int age) {
if (age < 0 || age > 150) {
throw new IllegalArgumentException("年龄必须在0-150之间");
}
}
public String getUserName(int userId) {
if (userId <= 0) {
throw new IllegalArgumentException("用户ID必须大于0");
}
// 模拟数据库查询
return "用户" + userId;
}
}
// 测试类
public class CalculatorTest {
private final Calculator calculator = new Calculator();
@Test
void testDivideByZero() {
ArithmeticException exception = assertThrows(
ArithmeticException.class,
() -> calculator.divide(10, 0)
);
assertEquals("除数不能为0", exception.getMessage());
}
@Test
void testValidateAgeInvalid() {
assertThrows(IllegalArgumentException.class,
() -> calculator.validateAge(-1));
assertThrows(IllegalArgumentException.class,
() -> calculator.validateAge(151));
}
@Test
void testGetUserNameWithNegativeId() {
Exception exception = assertThrows(
IllegalArgumentException.class,
() -> calculator.getUserName(-5)
);
assertTrue(exception.getMessage().contains("用户ID"));
}
}
assertDoesNotThrow - 断言不抛出异常
用于验证代码执行过程中没有抛出任何异常:
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
@Test
void testNoException() {
assertDoesNotThrow(() -> {
// 这段代码不应该抛出异常
int result = 10 / 2;
});
}
@Test
void testSuccessfulOperation() {
assertDoesNotThrow(() -> {
calculator.validateAge(25);
});
}
多异常类型断言
@Test
void testMultipleExceptions() {
// 验证不同的输入导致不同的异常
assertThrows(IllegalArgumentException.class,
() -> calculator.validateAge(-1));
assertThrows(IllegalArgumentException.class,
() -> calculator.validateAge(151));
// 正常情况不抛出异常
assertDoesNotThrow(() -> calculator.validateAge(25));
}
异常链测试
@Test
void testExceptionChain() {
Exception exception = assertThrows(RuntimeException.class, () -> {
try {
throw new IOException("IO错误");
} catch (IOException e) {
throw new RuntimeException("运行时错误", e);
}
});
assertEquals("运行时错误", exception.getMessage());
assertNotNull(exception.getCause());
assertTrue(exception.getCause() instanceof IOException);
}
测试自定义异常
// 自定义异常
class BusinessException extends RuntimeException {
private final int errorCode;
public BusinessException(int errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
public int getErrorCode() {
return errorCode;
}
}
// 测试
@Test
void testCustomException() {
BusinessException exception = assertThrows(
BusinessException.class,
() -> {
throw new BusinessException(1001, "业务异常");
}
);
assertEquals(1001, exception.getErrorCode());
assertEquals("业务异常", exception.getMessage());
}
使用 Lambda 表达式的高级用法
@Test
void testExceptionWithConditions() {
// 使用lambda表达式进行更复杂的验证
assertThrows(IllegalArgumentException.class, () -> {
// 复杂的业务逻辑
String input = "invalid";
if (input.length() > 5) {
throw new IllegalArgumentException("输入过长");
}
});
}
最佳实践
public class ExceptionTestBestPractices {
// 1. 明确测试目的
@Test
void shouldThrowExceptionWhenInputIsNegative() {
assertThrows(IllegalArgumentException.class,
() -> new Calculator().validateAge(-1));
}
// 2. 使用有意义的测试方法名
@Test
void divideByZero_ShouldThrowArithmeticException() {
assertThrows(ArithmeticException.class,
() -> new Calculator().divide(10, 0));
}
// 3. 避免过度使用assertThrows
@Test
void shouldNotThrowExceptionForValidInput() {
assertDoesNotThrow(() -> {
new Calculator().validateAge(30);
});
}
// 4. 测试边界值
@Test
void boundaryValueTesting() {
// 测试年龄边界值
assertThrows(IllegalArgumentException.class,
() -> new Calculator().validateAge(-1));
assertThrows(IllegalArgumentException.class,
() -> new Calculator().validateAge(151));
assertDoesNotThrow(() -> new Calculator().validateAge(0));
assertDoesNotThrow(() -> new Calculator().validateAge(150));
}
}
- assertThrows:验证代码抛出指定异常,可获取异常对象进行进一步检查
- assertDoesNotThrow:验证代码不抛出任何异常
- 异常链测试:可以测试异常的cause和层级关系
- 最佳实践:测试方法名要清晰,测试边界值,避免过度测试
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播