7

以下のコード例では、testMethod() が main() 経由で実行される場合は期待どおりに動作しますが、JUNIT 経由で実行される場合は MyUncaughtExceptionHandler が呼び出されません。

これについて何か説明はありますか?

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

2 に答える 2

7

明らかに、setUncaughtExceptionHandlerキャッチされていない例外のセット ハンドラーです。しかし、JUnit はテスト メソッドからスローされたすべての例外をキャッチします。

とにかく、単体テストのやり方が変です。単体テストでは、JVM 仕様ではなく、コードをテストする必要があります。

次のような単体テストを想像します。

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)
  }
}
于 2013-08-01T12:45:15.353 に答える