如何为未捕获的线程异常处理程序编写单元测试.

Dav*_*ave 6 java junit android unit-testing uncaught-exception

我正在尝试为我的应用程序编写一个单元测试未被捕获的线程异常处理程序,但到目前为止还没有运气.处理程序是应用程序范围的,我知道它的工作原理.它也基于此处的代码.但是我想不出一种实际为它编写单元测试的方法,考虑到如果我从我的测试项目中抛出一个异常就输入了那个代码,但它永远不会返回.这导致我到目前为止所写的任何测试都失败了.

这是我的处理程序,有没有人有任何建议如何我可以单元测试这个?

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);
    }
Run Code Online (Sandbox Code Playgroud)

我的包含测试的项目与我的实际应用程序项目是分开的.我已尝试在代码中设置标志,但在调用异常后,我的测试已经失败,并且没有机会检查是否已设置标志.我想过可能在未捕获的异常处理程序中添加一个广播并触发它,或者可能使用首选项并以某种方式重新运行测试以检查首选项是否已更改,但这不是非常可靠,我希望如果可能的话,为了测试而避免插入过多的额外代码.

谢谢!

use*_*068 7

我猜你的测试框架正在捕获所有异常(junit这样做),因此永远不会调用UncaughtExceptionHandler.

但是,如果运行启动新线程的测试,则框架不应捕获该线程中的异常.例如:

public void testUncaughtExceptionhandler()
{
  Thread testThread = new Thread()
  {
    public void run()
    {
      throw new RuntimeException("Expected!");
    }
  };

  testThread.start();
  testThread.join();
}
Run Code Online (Sandbox Code Playgroud)

这应该成功抛出一个将被UncaughtExceptionHandler捕获的异常.

这是测试是否在正确的时间调用UncaughtExceptionHandler.要测试处理程序是否正确响应,您只需调用:

_unCaughtExceptionHandler.uncaughtException(thread, ex);
Run Code Online (Sandbox Code Playgroud)

把它交给一个线程和一个Throwable.这将测试处理程序在运行时是否正常运行.

这两个测试验证设置默认处理程序的代码是否正确以及处理程序本身是否正确.这些是不同的问题,测试两者都很有用.

我发现junit可能依赖于使用自己的UncaughtExceptionHandler,所以当你覆盖它时,你就破坏了框架.如果是这种情况,您可能需要构建并运行测试而不使用junit.