是否可以测试即使捕获到异常是否抛出?

Is it possible to test if exception was thrown even if it was caught?

如果在 try / catch 块中捕获了主代码函数 eaven 中抛出的适当异常,是否可以 @Test?

例如:

public int maxSum(int a, int b) {
    try {
        if (a + b > 100)
            throw new TooMuchException("Too much! Sum reduced to 50");
    } catch (TooMuchException e) {
        System.out.println(e);
        return 50;
    }
    return a + b;
} 

由这样的人测试

@Test
void maxSum_TooMuchExceptionThrowedAndCatchedWhenSumOfNumbersIsOver100() {
    Service service = new Service();
    assertThatThrownBy(() -> {
        service.maxSum(55, 66);
    }).isInstanceOf(TooMuchException.class)
            .hasMessageContaining("Too much! Sum reduced to 50");
}

.

public class TooMuchException extends Throwable {
    public TooMuchException(String message) {
        super(message);
        }
}

测试异常不是消息。

我关心这个是因为我希望能够在不使程序崩溃的情况下捕获函数中的异常。

测试的工作是确认代码的行为是否符合预期,这意味着:代码执行了它需要执行的操作。测试不应验证实现细节。

你抛出并捕获的异常是一个实现细节,因为外部程序不知道或不关心它。在这种情况下,查看此代码并得出结论认为在此处抛出异常是无用的(或者性能很差,因为创建堆栈跟踪需要成本)并且应该将其删除是非常合理的。然而,如果您在测试中添加代码以某种方式检查异常,比如通过读取写入 stdout 的堆栈跟踪(如果您知道 io 类,非常可行),那么您将拥有浪费您的时间来实施该检查,并且您还将为更改实施的任务做额外的工作。必须有人查看它、理解它并检查它是否可以安全删除。

这就是我们尽量避免测试实现细节的原因,我们总是有可能遇到需要修改我们的实现的缺陷或性能问题或设计变更。我们不能总是避免重写测试,有时部分问题是合同定义不正确或环境变化使其无关紧要。但是,如果我们只有测试检查行为,那么我们就有更好的机会编写新的实现,并 运行 它针对旧测试,验证新版本是否执行旧版本所做的。更新测试是一项工作,我们希望在维护测试时尽量减少工作量。