JUnit 3.x and the Event Dispatch Thread

This is a recycled post from version 1 of this blog.

public abstract class EdtTestCase extends TestCase {

  /**
   * Overriding this method guarantees that setUp(), tearDown(), and all
   * tests run on the EDT.
   */
  @Override
  public void runBare() throws Throwable {
    final AtomicReference<Throwable> problem = new AtomicReference<Throwable>();
    if (!SwingUtilities.isEventDispatchThread()) {
      SwingUtilities.invokeAndWait(new Runnable() {
        public void run() {
          try {
            runBare();
          } catch (Throwable throwable) {
            problem.set(throwable);
          }
        }
      });
      if (problem.get() != null) {
        throw problem.get();
      }
    } else {
      super.runBare();
    }
  }
}

Does anyone have a comparable JUnit 4 example?


4 Responses to “JUnit 3.x and the Event Dispatch Thread”

Carey Says:

Unlike JUnit 3, in JUnit 4 it looks like you write a Runner that switches to the EDT for you, then add @RunWith(EDTRunner.class) to the test. Something like:

public class EDTRunner extends
    org.junit.internal.runners.TestClassRunner {
  public EDTRunner(Class klass)
        throws org.junit.internal.runners.InitializationError {
    super(klass);
  }

  @Override
  public void run(final org.junit.runner.notification.RunNotifier notifier) {
    if (javax.swing.SwingUtilities.isEventDispatchThread()) {
      super.run(notifier);
      return;
    }
    try {
      javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
        public void run() {
          EDTRunner.super.run(notifier);
        }
      });
    } catch (InterruptedException e) {
      notifier.fireTestFailure(new org.junit.runner.notification.Failure(
        getDescription(), e));
    } catch (java.lang.reflect.InvocationTargetException e) {
      notifier.fireTestFailure(new org.junit.runner.notification.Failure(
        getDescription(), e.getCause()));
    }
  }
}

I will probably regret extending an internal class.

Eric Burke Says:

Carey, I hope you don’t mind me editing your comment…I wrapped the code in a <pre class=”prettyprint”> element and changed the indentation.

Carey Says:

No problem. It was wrapped in pre tags and indented before I clicked submit; thank you, Wordpress.

Laird Nelson Says:

Hey there; I like this entry and the JUnit4 specific bit in the comments section.

To either of you: have you had any luck using this construct in something like a Maven test runner? No matter what wizardry I try to bring to bear on the problem, the net result is that my properly-EDTized tests pop their frames (or dialogs or whatever) up for the briefest of seconds and exit immediately. While sometimes this is valuable, and I’m glad to understand how to make it happen, what should I do in the guts of EDTRunner to make it so that any visual artifacts produced by my tests–frames and windows and whatnot–”stick around”? Normally, in an application, I wouldn’t have to do anything–the mere presence of a frame’s being visible on the EDT causes the application to stick around until that frame is disposed, and until all non-daemon threads exit. But for some reason when I run my JUnit4 tests under, in this case, Maven’s surefire plugin, there is nothing I can figure out to do to cause my frames to stick around.

Any ideas heartily welcomed.

THanks,
Laird

Leave a Reply