Java Thread.currentThread().setUncaughtExceptionHandler() not working with JUNIT?

风格不统一 提交于 2019-12-23 08:59:14

问题


In the example code below, if the testMethod() is run via main() it works as expected but if it is run via JUNIT then MyUncaughtExceptionHandler does not get called.

Is there some explanation for this?

package nz.co.test;

import java.lang.Thread.UncaughtExceptionHandler;

import org.junit.Test;

public class ThreadDemo {

  private void testMethod() {
    Thread.currentThread().setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());

    Object b = null;
    // Cause a NPE
    b.hashCode();
  }

  @Test
  public void testJunit() {
    // Run via JUnit and MyUncaughtExceptionHandler doesn't catch the Exception
    testMethod(); 
  }

  public static void main(String[] args) {
    // Run via main() works as expected
    new ThreadDemo().testMethod();
  }

  static class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {

    @Override
    public void uncaughtException(Thread t, Throwable e) {
      System.out.println("I caught the exception");
    } 
  }
}

回答1:


This is because all exception that are thrown in a test are caught and processed by JUnit, so UncaughtExceptionHandler doesnt get any uncaught exceptions. It is done in org.junit.runners.ParentRunners

...
    protected final void runLeaf(Statement statement, Description description,
            RunNotifier notifier) {
        EachTestNotifier eachNotifier = new EachTestNotifier(notifier, description);
        eachNotifier.fireTestStarted();
        try {
            statement.evaluate();   <-- test method execution is called from here
        } catch (AssumptionViolatedException e) {
            eachNotifier.addFailedAssumption(e);
        } catch (Throwable e) {
            eachNotifier.addFailure(e);
        } finally {
            eachNotifier.fireTestFinished();
        }
    }



回答2:


Obviously, the setUncaughtExceptionHandler sets handler for uncaught exceptions. But JUnit catches all exceptions thrown from test methods.

Anyway, it is weird way to make a unit test. Unit test should test your code, not JVM specification.

I imagine a unit test like this:

public class MyUncaughtExceptionHandlerTest
{
  @Mock Thread thread;
  MyUncaughtExceptionHandler testObject = new MyUncaughtExceptionHandler();

  @Before
  public void setUp()
  {
     MockitoAnnotations.initMocks(this);
  }

  @Test
  public void handleNpeShouldDoOneThing()
  {
    testObject.handleException(thread, new NullPointerException());
    //verify(oneThing)
  }

  @Test
  public void handleOomShouldDoSomethingElse()
  {
    testObject.handleException(thread, new OutOfMemoryError());
    //verify(somethingElse)
  }
}


来源:https://stackoverflow.com/questions/17994335/java-thread-currentthread-setuncaughtexceptionhandler-not-working-with-junit

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!