主要想法是考虑您的测试在 FX 线程内运行。当您创建一个扩展应用程序的类时,您实际上创建了一个进程。这就是您要测试的内容。
因此,要在应用程序上启动一些单元测试,首先创建一个扩展应用程序的 FXAppTest,然后在 FXAppTest 中启动单元测试。这是想法。
这是一个使用 JUnit 的示例。我创建了一个 Runner,它在 FXApp 中启动测试以进行测试。这是 FxApplicationTest 的代码示例(我们在其中启动单元测试)
public class FxApplicationTest extends Application {
private volatile boolean isStopped;
@Override
public void start(final Stage stage) {
StackPane root = new StackPane();
Scene scene = new Scene(root, 10, 10);
stage.setScene(scene);
}
public void startApp() {
launch();
}
public void execute(final BlockJUnit4ClassRunner runner, final RunNotifier notifier) throws InterruptedException {
isStopped = false;
Platform.runLater(new Runnable() {
@Override
public void run() {
runner.run(notifier);
isStopped = true;
}
});
while (!isStopped) {
Thread.sleep(100);
}
}
和亚军:
import org.apache.log4j.Logger;
import org.junit.runner.Description;
import org.junit.runner.Runner;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
public class JUnitFxRunner extends Runner {
private final BlockJUnit4ClassRunner runner;
private final Logger LOGGER = Logger.getLogger(JUnitFxRunner.class);
public JUnitFxRunner(final Class<?> klass) throws InitializationError {
super();
runner = new BlockJUnit4ClassRunner(klass);
}
@Override
public Description getDescription() {
return Description.EMPTY;
}
@Override
public void run(final RunNotifier notifier) {
try {
final FxApplicationTest fxApplicationTest = new FxApplicationTest();
MyTestRunner runnable = new MyTestRunner(runner, notifier, fxApplicationTest);
new Thread(runnable).start();
Thread.sleep(100);
runnable.execute();
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
private class MyTestRunner implements Runnable {
private final BlockJUnit4ClassRunner runner;
private final RunNotifier notifier;
private final FxApplicationTest fxApp;
public MyTestRunner(final BlockJUnit4ClassRunner runner, final RunNotifier notifier, final FxApplicationTest fxApp) {
this.runner = runner;
this.notifier = notifier;
this.fxApp = fxApp;
}
@Override
public void run() {
fxApp.startApp();
}
public void execute() throws InterruptedException {
fxApp.execute(runner, notifier);
}
}
}
现在,只需使用 runner 启动测试:
import fr.samarie_projects.fx.utils.JUnitFxRunner;
@RunWith(JUnitFxRunner.class)
public class MainFxAppTest {
@org.junit.Test
public void testName() throws Exception {
MainFxApp fxApp = new MainFxApp();
fxApp.start(new Stage());
}
}
本单元测试 MainFxApp
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class MainFxApp extends Application {
@Override
public void start(final Stage stage) throws Exception {
StackPane root = new StackPane();
Scene scene = new Scene(root, 10, 10);
stage.setScene(scene);
}
public static void main(final String[] args) {
launch(args);
}
}
当然,需要审查此代码。它只是提出这个想法。