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

时间:2017-05-31 07:08:26

标签: java unit-testing exception junit exception-handling

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

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

我尝试使用UncaughtExceptionHandler执行此操作。这似乎在运行项目时起作用,但不是在JUnit中,因为它将每个测试包装在try {catch块中,如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>

1 个答案:

答案 0 :(得分:2)

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

有关详细信息,请参阅here

因此,你必须做两个事情:

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

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

B) plumbing - 你想确保你的代码实际设置了这个特定的未被捕获的处理程序:

@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)

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