gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-31 20:28:13 27 4
gpt4 key购买 nike

我有一个 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);
}
}

最佳答案

Application.launch方法在应用程序退出之前不会返回,要么通过调用 Platform.exit或者所有应用程序窗口都已关闭,因此您必须将其包装到另一个线程中才能终止它。

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

但是,我设法通过使用 Thread.interrupt 来做到这一点。只需在包装线程内运行您的 JavaFX 应用程序,等待一段时间,然后中断您的包装线程。这样 JavaFX 应用程序将被中断并抛出 InterruptedException。如果它没有抛出,则说明启动 JavaFX 应用程序时出现问题。

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

测试类

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

JavaFX 应用程序类

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();
}
}

关于java - 如何对 JavaFX 应用程序启动进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24851886/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com