我试图为我的应用程序编写一个单元测试未被捕获的线程异常处理程序,但到目前为止还没有运气。处理程序是应用程序范围的,我知道它的工作原理。它也基于找到的代码here。但是,我无法想出一种方法来为它实际编写单元测试,考虑到如果我从我的测试项目中抛出一个异常,它就会输入该代码,但它永远不会返回。这导致我到目前为止所写的任何测试都失败了。
这是我的处理程序,有没有人有任何建议我如何进行单元测试?
public class MyApplication extends Application {
// uncaught exception handler variable
private final UncaughtExceptionHandler defaultUEH;
// handler listener
private final Thread.UncaughtExceptionHandler _unCaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable ex) {
// Try restarting the application if an uncaught exception has
// occurred.
PendingIntent myActivity = PendingIntent
.getActivity(getApplicationContext(), 192837, new Intent(
getApplicationContext(), MainGui.class), PendingIntent.FLAG_ONE_SHOT);
AlarmManager alarmManager;
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 15000, myActivity);
System.exit(2);
// re-throw critical exception further to the os (important)
defaultUEH.uncaughtException(thread, ex);
}
};
public MyApplication() {
defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
// setup handler for uncaught exception
Thread.setDefaultUncaughtExceptionHandler(_unCaughtExceptionHandler);
}
包含测试的项目与我的实际应用程序项目是分开的。我已尝试在代码中设置标志,但在调用异常后,我的测试已经失败,并且没有机会检查是否已设置标志。我想过可能在未捕获的异常处理程序中添加一个广播并触发它,或者可能使用偏好并以某种方式重新运行测试来检查偏好已经改变,但这并不是非常可靠的并且我想避免为了测试而插入的额外代码太多,如果可能的话。
谢谢!
答案 0 :(得分:7)
我猜你的测试框架正在捕获所有异常(junit这样做),因此永远不会调用UncaughtExceptionHandler。
但是,如果运行启动新线程的测试,则框架不应捕获该线程中的异常。例如:
public void testUncaughtExceptionhandler()
{
Thread testThread = new Thread()
{
public void run()
{
throw new RuntimeException("Expected!");
}
};
testThread.start();
testThread.join();
}
这应该成功抛出一个将被UncaughtExceptionHandler捕获的异常。
这是测试是否在正确的时间调用UncaughtExceptionHandler。要测试处理程序是否正确响应,您只需调用:
_unCaughtExceptionHandler.uncaughtException(thread, ex);
把它交给一个线程和一个Throwable。这将测试处理程序在运行时是否正常运行。\
这两个测试验证设置默认处理程序的代码是否正确以及处理程序本身是否正确。这些是不同的问题,测试两者都很有用。
我认为junit可能依赖于使用自己的UncaughtExceptionHandler,所以当你重写它时,你就破坏了框架。如果是这种情况,您可能需要构建并运行测试而不使用junit。