【问题标题】:Wait for Platform.RunLater in a unit test在单元测试中等待 Platform.RunLater
【发布时间】:2014-04-02 19:26:10
【问题描述】:

我有一个表示类存储一个 XYChart.Series 对象并通过观察模型来更新它。系列更新是通过使用 Platform.runLater(...)

我想对此进行单元测试,确保 runLater 中的命令正确执行。如何告诉单元测试等待 runLater 命令完成? 现在我所做的只是测试线程上的 Thread.Sleep(...) 给 FXApplicationThread 完成的时间,但这听起来很愚蠢。

【问题讨论】:

    标签: java unit-testing javafx-2 javafx-8


    【解决方案1】:

    我解决的方法如下。

    1) 像这样创建一个简单的信号量函数:

    public static void waitForRunLater() throws InterruptedException {
        Semaphore semaphore = new Semaphore(0);
        Platform.runLater(() -> semaphore.release());
        semaphore.acquire();
    
    }
    

    2) 当您需要等待时,请致电waitForRunLater()。因为Platform.runLater()(根据javadoc)按照提交的顺序执行runnables,你可以在测试中编写:

    ...
    commandThatSpawnRunnablesInJavaFxThread(...)
    waitForRunLater(...)
    asserts(...)`
    

    适用于简单测试

    【讨论】:

    • 如果 JavaFX 线程抛出异常,可能需要将 semaphore.release() 包装在 try-finally 块中
    【解决方案2】:

    要在 AssertJ 样式语法中添加更多内容,您可以执行以下操作:

        @Test
        public void test() throws InterruptedException {
            // do test here
    
            assertAfterJavaFxPlatformEventsAreDone(() -> {
                // do assertions here
           }
        }
    
        private void assertAfterJavaFxPlatformEventsAreDone(Runnable runnable) throws InterruptedException {
            waitOnJavaFxPlatformEventsDone();
            runnable.run();
        }
    
        private void waitOnJavaFxPlatformEventsDone() throws InterruptedException {
            CountDownLatch countDownLatch = new CountDownLatch(1);
            Platform.runLater(countDownLatch::countDown);
            countDownLatch.await();
        }
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用在 runLater 之前创建的 CountDownLatch 并在 Runnable 结束时倒计时

      【讨论】:

        猜你喜欢
        • 2016-03-20
        • 1970-01-01
        • 2019-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-26
        • 1970-01-01
        • 2014-11-24
        相关资源
        最近更新 更多