JavaFX应用程序线程在JUnit测试期间退出

时间:2015-03-24 15:15:47

标签: junit javafx javafx-8

我正在使用JUnit测试JavaFX应用程序。在大多数情况下,我使用Basic JUnit test for JavaFX 8中的@Rule方法。但是有一些情况下这种方法不起作用,所以我手动设置了JavaFX平台,并在必要时调用Platform.runLater()。

似乎正在发生的事情是,在某些时候JavaFX应用程序线程正在消失,这意味着随后的测试锁定,因为Platform.runLater()调用永远不会返回 - 这就是为什么我在示例中添加了超时。我通过调用Thread.getAllStackTraces()

证明了这一点
  • 是的我知道JemmyFX,我很快就会接受它,但我仍然想知道这里发生了什么......

代码

public class JavaFxThreadJUnit {
    private static boolean setup;
    private Stage stage;

    @Before
    public void before() throws Exception {
        setupJavaFX();
        Platform.setImplicitExit(true);
        CountDownLatch latch = new CountDownLatch(1);
        Platform.runLater(() -> {
            stage = new Stage();
            stage.show();
            latch.countDown();
        });
        latch.await(5, TimeUnit.SECONDS);
    }

    @After
    public void after() throws Exception {
        CountDownLatch latch = new CountDownLatch(1);
        Platform.runLater(() -> {
            stage.hide();
            latch.countDown();
        });
        latch.await(5, TimeUnit.SECONDS);
    }

    @Test
    public void foo() throws Exception {
        // test stuff...
        System.out.println("foo test: "
                + Thread.getAllStackTraces().keySet().stream().map(Thread::getName).collect(Collectors.toList()));
    }

    @Test
    public void bar() throws Exception {
        // test stuff...
        System.out.println("bar test: "
                + Thread.getAllStackTraces().keySet().stream().map(Thread::getName).collect(Collectors.toList()));
    }

    // https://gist.github.com/andytill/3835914
    public static void setupJavaFX() throws InterruptedException {
        if (setup) {
            return;
        }

        long timeMillis = System.currentTimeMillis();

        final CountDownLatch latch = new CountDownLatch(1);

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                // initializes JavaFX environment
                new JFXPanel();

                latch.countDown();
            }
        });

        System.out.println("javafx initialising...");
        latch.await();
        System.out.println("javafx is initialised in " + (System.currentTimeMillis() - timeMillis) + "ms");
        setup = true;
    }

}

输出...... JavaFX应用程序线程在那里,然后就消失了......

javafx initialising...
javafx is initialised in 327ms
bar test: [Thread-3, ReaderThread, AWT-Shutdown, AWT-Windows, Thread-2, Finalizer, JavaFX Application Thread, Signal Dispatcher, Java2D Disposer, AWT-EventQueue-0, main, Attach Listener, Reference Handler, QuantumRenderer-0]
foo test: [Thread-3, ReaderThread, Java2D Disposer, AWT-Windows, Thread-2, main, Finalizer, Attach Listener, Reference Handler, Signal Dispatcher]

1 个答案:

答案 0 :(得分:1)

看起来舞台关闭正在触发"implicit exit"。我仍然有兴趣知道为什么这也不会影响使用@Rule方法的测试...

解决方法:

Platform.setImplicitExit(false)