Question

I'm trying to write a unit test for my applications uncaught thread exception handler, but have had no luck so far. The handler is application wide, and I know it works. It was also based around code found here. However I can't think of a way to actually write a unit test for it, considering that if I throw an exception from my test project it is entering that code, but it never returns. This causes any test that I've so far written to fail out.

Here is my handler, does anyone have any suggestions how I can unit test this?

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);
    }

My project that contains the tests is separate from my actual application project. I've tried setting flags in the code, but after the exception is called, my test has already failed and there is no opportunity to check that flags have been set. I've thought of maybe adding a broadcast in the uncaught exception handler and triggering off that, or maybe to use preferences and somehow re-run the test to check the preference has changed, but that doesn't seam very reliable and I would like to avoid too much extra code that is just inserted for the sake of testing if that is possible.

Thanks!

Was it helpful?

Solution

I would guess that your test framework is catching all exceptions (junit does this), so the UncaughtExceptionHandler is never called.

However, if you run a test that starts a new Thread, the framework should not catch exceptions in that Thread. For example:

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

  testThread.start();
  testThread.join();
}

That should successfully throw an exception that would be caught by the UncaughtExceptionHandler.

What this is testing is whether the UncaughtExceptionHandler is called at the right time. To test whether the handler responds correctly, you can simply call:

_unCaughtExceptionHandler.uncaughtException(thread, ex);

handing it a Thread and a Throwable. This will test whether the handler will behave correctly when it does run.\

These two tests verify whether the code that sets the default handler is correct and whether the handler itself is correct. These are different issues, and it is useful to test both.

It occurs to me that junit may rely on using its own UncaughtExceptionHandler, so when you override that, you break the framework. If that is the case, you might need to build and run the test without using junit.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top