Java 从一种异常转换为另一种异常

标签 java unit-testing junit exception

我有一个公共(public)项目,其中有一些共享代码正在另一个项目中使用。我正在尝试将公共(public)项目 CommonException 中的异常转换/映射为新类型的异常,我们将其称为 SuperAwesomeException

目标是有一个通用的方法来处理项目中的所有自定义异常。

我尝试使用 UncaughtExceptionHandler 来执行此操作。这似乎在运行项目时有效,但在 JUnit 中无效,因为它将每个测试包装在 try/catch block 中,如所述 here 所示。 .

public final class ExceptionHandler implements Thread.UncaughtExceptionHandler {        
    @Override
    public void uncaughtException(Thread thread, Throwable exception) {            
        if (exception instanceof CommonException) {
            throw new SuperAwesomeException(exception.getMessage());
        }
        if (exception instanceof SuperAwesomeException) {
            throw new CommonException(exception.getMessage());
        }
        else {
            System.out.println("ERROR! caught some other exception I don't really care about");
            System.out.println("Not doing anything");    
        }
    }
}

是否有另一种方法可以从一个异常映射到另一个异常,或者我可以以某种方式告诉 JUnit 不要捕获某些异常并检查异常是否映射到正确的异常?

更新 - 我最初尝试编写测试的方式:

public class ClassThatThrowsException {
    ClassThatThrowsException() {
        Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler());
    }

    public void doSomething() {
        throw new CommonException("Something boring blew up!");
    }
}

public class ClassThatThrowsExceptionTest {    
    @Test(expected=SuperAwesomeException.class)
    public void testAwesome() {
        ClassThatThrowsException c = new ClassThatThrowsException();
        c.doSomething();
    }
}

抛出:

java.lang.Exception: Unexpected exception, expected<SuperAwesomeException> but was<CommonException>

最佳答案

问题是:当您使用JUnit时,框架将捕获您的异常。因此,未捕获异常处理程序首先不会被调用!

参见here了解更多详情。

因此,您必须做两件事:

A) 编写测试以确保您的异常处理程序实现按预期工作

@Test(expected=SuperAwesomeException.class)
public void testAwesome() {
   new ExceptionHandler().uncaughtException(null, new CommonException("whatever"));
}

B) 最管道 - 您想要确保这个特定的未捕获处理程序实际上由您的代码设置:

@Test
public void testDefaultHandlerIsSet() {
   // creating a new instance should update the handler!
   new ClassThatThrowsException();
   Thread.UncaughtExceptionHandler handler = Thread.getDefaultUncaughtExceptionHandler();
   assertThat(handler, not(nullValue()));
   assertThat(handler, instanceOf(ExceptionHandler.class));
}

最后 - 请注意:您不应该只执行new XException(oldException.getMessage)。而是选择 new XException("some message, oldException)

换句话说:你在这里有一个原因;因此,您最好在要抛出的新异常中使用传入的异常作为原因。否则您将丢失所有堆栈跟踪信息。

关于Java 从一种异常转换为另一种异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44277959/

相关文章:

java - JUnit - 测试方法中使用的模拟类

java - 使用 Spring JDBC 连接数据库

java - 如何移动 JTree 中的节点?

java - react 堆项目 : downstream is slow

java - 在没有静态测试数据库的情况下,如何使 DAO 类的单元测试不那么脆弱?

javascript - 仅模拟模块中的一项功能,但保留原始功能

c# - 单元测试遗留代码 : limits of "extract and override" vs JustMock/TypeMock/moles?

java - 错误 :(27, 0) android studio 错误

java - 为什么 DoubleStream.sum() 的结果与直接加法不同?

junit - 无法使用 PowerMockito 部分模拟静态方法