Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何对JavaFX应用程序启动进行单元测试_Java_Unit Testing_Javafx_Javafx 8_Testfx - Fatal编程技术网

如何对JavaFX应用程序启动进行单元测试

如何对JavaFX应用程序启动进行单元测试,java,unit-testing,javafx,javafx-8,testfx,Java,Unit Testing,Javafx,Javafx 8,Testfx,我有一个JavaFX应用程序,我想测试它是否启动。我该怎么做呢?是否可以只使用JUnit,或者TestFX可以在这方面帮助我 我的主要问题是:如何在应用程序(成功)启动后立即关闭它 示例应用程序类: public class MovieDB extends Application { @Override public void start(final Stage primaryStage) throws IOException { FXMLLoader fxmlL

我有一个JavaFX应用程序,我想测试它是否启动。我该怎么做呢?是否可以只使用JUnit,或者TestFX可以在这方面帮助我

我的主要问题是:如何在应用程序(成功)启动后立即关闭它

示例应用程序类:

public class MovieDB extends Application {
    @Override
    public void start(final Stage primaryStage) throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(MovieDBController.class.getResource("MovieDB.fxml"), ResourceBundle.getBundle("bundles/bundle", new Locale("en")));
        Parent root = fxmlLoader.load();

        Scene scene = new Scene(root, 1024, 768);

        StyleManager.getInstance().addUserAgentStylesheet(getClass().getResource("/css/MovieDB.css").getPath());

        primaryStage.setTitle("MovieDB");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

假设primaryStage是唯一打开的阶段,那么当您调用primaryStage.hide()时,JavaFX线程将自动关闭。这是因为当所有阶段都隐藏时,JavaFX默认设置为shutdown,可以通过调用
Platform.setImplicitExit(false)
进行更改

更多信息。

由于该方法在应用程序退出之前不会返回,无论是通过调用还是关闭所有应用程序窗口,因此您必须将其包装到另一个线程中才能终止它

如果在JavaFX应用程序启动后立即调用Platform.exit,您将获得IllegalStateException。如果您等待一段时间以便初始化JavaFX应用程序,然后调用Platform.exit,则JavaFX应用程序和包装线程都将终止,而不会完成或引发任何异常。我无法通过使用Platform.exit找到解决这个问题的方法

然而,我通过使用Thread.interrupt成功地做到了这一点。只需在包装线程内运行JavaFX应用程序,等待一段时间,然后中断包装线程。这样JavaFX应用程序将被中断并抛出InterruptedException。如果它没有抛出,那么启动JavaFX应用程序就会出现问题

请注意,启动JavaFX应用程序可能需要比等待JVM更长的时间,因此此方法不能保证JavaFX应用程序在正确启动后被中断,这可能会导致误报情况。

测试班 JavaFX应用程序类
应用程序。启动
签名不是
对象
。它是
Application.launch(
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import static org.junit.Assert.assertTrue;
import org.junit.Test;

public class JavaFXTest {

    // Wrapper thread updates this if
    // the JavaFX application runs without a problem.
    // Declared volatile to ensure that writes are visible to every thread.
    private volatile boolean success = false;

    /**
     * Test that a JavaFX application launches.
     */
    @Test
    public void testMain() {
        Thread thread = new Thread() { // Wrapper thread.
            @Override
            public void run() {
                try {
                    Application.launch(JavaFXTest.class); // Run JavaFX application.
                    success = true;
                } catch(Throwable t) {
                    if(t.getCause() != null && t.getCause().getClass().equals(InterruptedException.class)) {
                        // We expect to get this exception since we interrupted
                        // the JavaFX application.
                        success = true;
                        return;
                    }
                    // This is not the exception we are looking for so log it.
                    Logger.getLogger(JavaFXTest.class.getName()).log(Level.SEVERE, null, t);
                }
            }
        };
        thread.setDaemon(true);
        thread.start();
        try {
            Thread.sleep(3000);  // Wait for 3 seconds before interrupting JavaFX application
        } catch(InterruptedException ex) {
            // We don't care if we wake up early.
        }
        thread.interrupt();
        try {
            thread.join(1); // Wait 1 second for our wrapper thread to finish.
        } catch(InterruptedException ex) {
            // We don't care if we wake up early.
        }
        assertTrue(success);
    }
}
import java.io.IOException;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class JavaFX extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws IOException {
        primaryStage.setTitle("JavaFX");
        Label label = new Label("Hello World!");
        StackPane root = new StackPane();
        root.getChildren().add(label);
        primaryStage.setScene(new Scene(root, 250, 250));
        primaryStage.show();
    }
}