
junit 4 引入了 @test 注解的一个 expected 参数,允许开发者声明一个测试方法预期会抛出的异常类型。如果测试方法抛出了指定的异常,测试通过;如果抛出了其他异常或没有抛出任何异常,测试失败。
示例代码:
假设我们有一个 B3_E2 类,其中包含一个 getMultiplesOfGivenNumber 方法,当 number 参数为零时会抛出 ArithmeticException。
import org.junit.Test;
import static org.junit.Assert.fail; // 用于演示如果异常未抛出
// 假设这是要测试的业务逻辑类
class B3_E2 {
public static int getMultiplesOfGivenNumber(int number, int[] array) {
if (number == 0) {
throw new ArithmeticException("Number cannot be zero");
}
// ... 其他业务逻辑 ...
return 0; // 简化处理
}
}
public class JUnit4ExpectedExceptionTest {
@Test(expected = ArithmeticException.class)
public void testDivideByZeroWithExpectedAnnotation() {
// 调用可能抛出异常的方法
B3_E2.getMultiplesOfGivenNumber(0, new int[]{1, 2, 3});
// 如果代码执行到这里,说明预期的 ArithmeticException 没有被抛出,测试将失败。
// @Test(expected=...) 会自动处理这种情况,无需手动调用 fail()。
}
}注意事项:
try-catch 块是一种更通用、更灵活的异常测试方法,适用于所有 JUnit 版本(包括 JUnit 3、4 和 5)。它允许开发者捕获到异常对象,并对其进行详细的检查。
示例代码:
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail; // 用于明确指示测试失败
// 假设这是要测试的业务逻辑类 (与上文相同)
class B3_E2 {
public static int getMultiplesOfGivenNumber(int number, int[] array) {
if (number == 0) {
throw new ArithmeticException("Number cannot be zero");
}
// ... 其他业务逻辑 ...
return 0; // 简化处理
}
}
public class TryCatchExceptionTest {
// 辅助方法,用于模拟数据
private int[] intervalFromOneToTen() {
return new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
}
@Test
public void testDivideByZeroWithTryCatch() {
try {
// 调用可能抛出异常的方法
B3_E2.getMultiplesOfGivenNumber(0, intervalFromOneToTen());
// 如果代码执行到这里,说明预期的异常没有被抛出,测试应该失败。
fail("Expected ArithmeticException was not thrown.");
} catch (ArithmeticException e) {
// 捕获到预期的 ArithmeticException,现在可以检查其消息或其他属性
assertEquals("Number cannot be zero", e.getMessage());
// 对于更复杂的异常,可以在这里检查更多的属性,例如 cause、自定义字段等。
} catch (Exception e) {
// 捕获到其他类型的异常,这不是我们预期的异常类型,测试也应失败。
fail("Thrown an unexpected exception type: " + e.getClass().getName());
}
}
}优势:
对于使用 JUnit 5 的项目,assertThrows 是官方推荐的异常测试方法。它结合了 @Test(expected=...) 的简洁性和 try-catch 的灵活性,通过 Lambda 表达式提供了一种更现代、更易读的异常断言方式。
示例代码:
import org.junit.jupiter.api.Test; // JUnit 5 的 @Test 注解
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertEquals;
// 假设这是要测试的业务逻辑类 (与上文相同)
class B3_E2 {
public static int getMultiplesOfGivenNumber(int number, int[] array) {
if (number == 0) {
throw new ArithmeticException("Number cannot be zero");
}
// ... 其他业务逻辑 ...
return 0; // 简化处理
}
}
public class JUnit5AssertThrowsTest {
// 辅助方法,用于模拟数据
private int[] intervalFromOneToTen() {
return new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
}
@Test
void testDivideByZeroWithAssertThrows() { // JUnit 5 的 @Test 方法可以不声明为 public
// 使用 assertThrows 捕获异常
ArithmeticException thrown = assertThrows(
ArithmeticException.class, // 期望的异常类型
() -> B3_E2.getMultiplesOfGivenNumber(0, intervalFromOneToTen()), // 包含可能抛出异常的代码
"Expected ArithmeticException to be thrown, but it wasn't" // 可选的失败消息
);
// 验证异常消息
assertEquals("Number cannot be zero", thrown.getMessage());
// 也可以进一步检查异常的其他属性
}
}优势:
在选择 JUnit 异常测试方法时,应根据您项目的 JUnit 版本、对异常检查的详细程度以及个人偏好来决定:
一般注意事项:
通过掌握这些异常测试方法,您可以编写出更全面、更健壮的单元测试,确保代码在异常情况下也能按预期行为。
以上就是如何在 JUnit 中测试代码抛出特定异常及自定义消息的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号