astralis541
astralis541

Reputation: 1

ExceptionInInitializerError with TestFX and Junit5

I am just getting familiar with Java and JavaFX, and am working on a simple project that tests a JavaFX UI. However, I don't think that I'm initializing the tests correctly, as I'm getting an ExceptionInInitializerError when I instantiate the app object. Here is the relevant part of my test file:

public class AppGuiTest extends ApplicationTest {
private App app = new App();

    @Override
    public void start(Stage stage) throws Exception {
        stage.setScene(app.getScene());
        stage.show();
        stage.toFront();
    }

//tests here 
}

It errors out when a label is defined within the app object:

Label message = new Label("Welcome!");

Here is the relevant part of my Gradle file:

plugins {
    id 'org.openjfx.javafxplugin' version '0.0.9'

}

dependencies {

    implementation 'org.testfx:testfx-junit:4.0.15-alpha'
    implementation 'org.loadui:testFx:3.1.2'

    implementation 'org.testfx:testfx-junit5:4.0.16-alpha'
    implementation 'org.junit.jupiter:junit-jupiter:5.8.1'
    implementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
}

javafx {
    version = "17"
    modules = [ 'javafx.controls' , 'javafx.base']
}

The JavaFX part runs fine by itself. It's only when I try to add the tests that I get the exception. Is this even how I should be initializing things? When I remove the app variable from the test file and comment out the contents of the tests, then the tests pass. If I don't have my app object defined, how do I test the UI elements?

I am not sure what to do to fix this error, so any input would be very helpful. Thanks in advance!

Upvotes: 0

Views: 854

Answers (1)

Oboe
Oboe

Reputation: 2713

You can use JUnit 5 tag @ExtendWith and TestFx ApplicationExtension class. You should also use @Start tag for the start method and initialize the Label (or App) there.

import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

import org.testfx.api.FxRobot;
import org.testfx.framework.junit5.ApplicationExtension;
import org.testfx.framework.junit5.Start;
import static org.testfx.assertions.api.Assertions.assertThat;

@ExtendWith(ApplicationExtension.class)
public class AppGuiTest {

    private Label message;

    @Start
    protected void start(Stage stage) {
        message = new Label("Welcome!");

        stage.setScene(new Scene(new StackPane(message)));
        stage.show();
    }

    @Test
    public void testMessage() {
        assertThat(message).hasText("Welcome!");
    }

    @Test
    public void testChangeMessage(FxRobot robot) {
        robot.interact(() -> message.setText("Bye!"));
        assertThat(message).hasText("Bye!");
    }

}

Your Gradle for JUnit 5 should look like this:

dependencies {
    testCompile 'org.junit.jupiter:junit-jupiter-api:5.8.2'
    testCompile "org.testfx:testfx-junit5:4.0.16-alpha"
    testCompile "org.testfx:testfx-core:4.0.16-alpha"
}

plugins {
    id 'org.openjfx.javafxplugin' version '0.0.10'
}

javafx {
    version = '17'
    modules = [ 'javafx.controls', 'javafx.fxml' ]
}

Upvotes: 1

Related Questions