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

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

Is there any 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"); } } } 
+6
source share
2 answers

This is because all exceptions that are thrown in the test are caught and handled by JUnit, so UncaughtExceptionHandler does not receive any uncaught exceptions. This 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(); } } 
+5
source

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

Anyway, this is a weird way to do a unit test. Unit test should check your code, not the JVM specification.

I imagine Unit test as follows:

 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) } } 
+7
source

Source: https://habr.com/ru/post/950815/


All Articles