【问题标题】:How to write a unit test for an uncaught thread exception handler.如何为未捕获的线程异常处理程序编写单元测试。
【发布时间】:2014-05-05 20:34:36
【问题描述】:

我正在尝试为我的应用程序未捕获线程异常处理程序编写单元测试,但到目前为止还没有运气。处理程序是应用程序范围的,我知道它有效。它也基于找到的代码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);
    }

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

谢谢!

【问题讨论】:

    标签: java android unit-testing junit uncaught-exception


    【解决方案1】:

    我猜你的测试框架正在捕获所有异常(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 的情况下构建和运行测试。

    【讨论】:

    • 除此之外,我突然想到UEH中的System.exit(2)可能会导致单元测试出现问题(导致JVM在测试框架完成之前退出)。可能有必要将其移至另一个方法,甚至是可以模拟用于测试目的的辅助类。
    • 这对我帮助很大。工作得很好!大卫康拉德的评论也很有用。感谢您的回复! :)
    猜你喜欢
    • 2019-04-25
    • 2011-05-20
    • 2021-10-17
    • 2019-12-16
    • 1970-01-01
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多