在 Java 中捕获通用异常?

2022-09-01 03:19:14

我们在工作中使用JUnit 3,没有注释。我想在我们的代码中添加一个实用程序来包装这个:ExpectedException

 try {
     someCode();
     fail("some error message");
 } catch (SomeSpecificExceptionType ex) {
 }

所以我试了一下:

public static class ExpectedExceptionUtility {
  public static <T extends Exception> void checkForExpectedException(String message, ExpectedExceptionBlock<T> block) {
     try {
        block.exceptionThrowingCode();
        fail(message);
    } catch (T ex) {
    }
  }
}

但是,我认为Java不能在捕获块中使用泛型异常类型。

我该如何做这样的事情,绕过Java的限制?

有没有办法检查变量的类型?exT


答案 1

您可以传入 Class 对象并以编程方式进行检查。

public static <T extends Exception> void checkForException(String message, 
        Class<T> exceptionType, ExpectedExceptionBlock<T> block) {
    try {
       block.exceptionThrowingCode();
   } catch (Exception ex) {
       if ( exceptionType.isInstance(ex) ) {
           return;
       } else {
          throw ex;  //optional?
       }
   }
   fail(message);
}

//...
checkForException("Expected an NPE", NullPointerException.class, //...

我不确定你是否想要重新被推翻;重新抛出同样会使测试失败/出错,但从语义上讲,我不会,因为它基本上意味着“我们没有得到我们预期的异常”,所以这代表了编程错误,而不是测试环境错误。


答案 2

我理解试图简化你的异常测试习语的冲动,但说真的:不要。你会想到的每一个可能的选择都是一种比疾病更糟糕的治疗方法。特别是JUnit 4的@ExpectedException胡说八道!这是一个过于聪明的框架解决方案,要求每个人都了解它是如何工作的,而不是一个不言而喻的常规Java代码。更糟糕的是,它无法仅包装您希望引发异常的测试部分,因此,如果前面的设置步骤引发相同的异常,即使您的代码已损坏,您的测试也将通过。

我可以在这里写一篇很长的抨击(我很抱歉没有足够的时间),因为我们在谷歌的Java工程师中对这个问题进行了长时间的讨论,共识是这些疯狂的解决方案都不值得。习惯尝试/捕捉,这真的不是那么糟糕。