如何使用JUnit 5测试Fraction类构造函数抛出算术异常?
解决JUnit 5测试构造函数抛出异常的问题
你碰到的问题核心在于assertThrows的参数要求:它的第二个参数必须是一个Executable函数式接口实例,用来包装需要测试的、可能抛出异常的代码逻辑。你原来的写法直接执行了new Fraction(2, 0),这会在assertThrows方法调用前就触发构造函数,提前抛出异常,同时这段代码也不符合Executable的类型要求,所以IDE会报错。
正确的写法有这几种:
1. 使用Lambda表达式(最简洁推荐)
Lambda是JUnit 5中测试异常最常用的方式,它能把构造函数调用包装成延迟执行的Executable:
@Test public void testZeroDenominator(){ assertThrows(ArithmeticException.class, () -> new Fraction(2, 0)); }
这里的() -> new Fraction(2, 0)就是一个Lambda表达式,它会在assertThrows内部被调用,这样异常就能被正确捕获。
2. 使用匿名内部类(兼容旧写法)
如果你对Lambda不太熟悉,也可以用匿名内部类实现Executable接口:
import org.junit.jupiter.api.function.Executable; import static org.junit.jupiter.api.Assertions.assertThrows; @Test public void testZeroDenominator(){ assertThrows(ArithmeticException.class, new Executable() { @Override public void execute() throws Throwable { new Fraction(2, 0); // 这里才执行构造函数 } }); }
3. 捕获异常并验证消息(进阶用法)
如果你还想验证抛出的异常消息是否符合预期,可以把assertThrows的返回值存起来,做进一步断言:
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertEquals; @Test public void testZeroDenominator(){ ArithmeticException thrownException = assertThrows(ArithmeticException.class, () -> new Fraction(2, 0)); assertEquals("Cannot divide by zero.", thrownException.getMessage()); }
为什么原来的代码不行?
你原来的代码assertThrows(ArithmeticException.class, f = new Fraction(2, 0))会先执行f = new Fraction(2, 0),这时候构造函数立刻运行并抛出异常,assertThrows根本没机会介入处理。同时,f = new Fraction(2, 0)的结果是Fraction对象,和Executable接口不兼容,所以IDE会提示类型错误。
内容的提问来源于stack exchange,提问作者TobyBBrown
相关产品推荐
相关产品推荐

