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

如何使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:20:47