The main goal is to run code when the scene is loaded and I know Initializable is the recommended solution and I've been using it except the problem I'm running into is that it's not conducive to integration testing.
The logic in my initialize method is dependent on previous scenes, so when I load up just this one screen, I get some NullPointer exceptions because some things I expected to exist do not exist.
There is no way for me to mock any of this because, using TestFX, the initialize method is run on the first line of setup, FXMLLoader loader = new FXMLLoader(getClass().getResource("test.fxml"));
.
From there, I would have done loader.getController();
to get access to the generated controller and mock certain class fields and stuff, but the issue is that I can't do this before the initialize method runs. It's a catch 22 situation because to get access to the controller javafx.fxml.FXMLLoader
must run, but when that runs it automatically executes the initialize method, which I would otherwise need to mock parts of, or generate expected information.
So, what are my options? Is there a way to run code at the start of a scene without Initializable?
public class GameScreenController implements Initializable {
private AppService appService;
private PlayerService playerService;
private DirectionService directionService;
private RoomDirectionService roomDirectionService;
@FXML
private javafx.scene.control.Button closeButton;
@FXML
private Label goldAmount;
@FXML
private ImageView player;
private final BooleanProperty wPressed = new SimpleBooleanProperty(false);
private final BooleanProperty aPressed = new SimpleBooleanProperty(false);
private final BooleanProperty sPressed = new SimpleBooleanProperty(false);
private final BooleanProperty dPressed = new SimpleBooleanProperty(false);
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
this.appService = new AppService();
this.directionService = new DirectionService();
this.roomDirectionService = new RoomDirectionService(this.directionService);
this.goldAmount.setText(String.valueOf(this.appService.getPlayerState().getGoldAmount()));
this.playerService = new PlayerService(this.player, this.appService,
this.roomDirectionService);
this.playerService.moveX(this.appService.getPlayerState().getSpawnCoordinates()[0]);
this.playerService.moveY(this.appService.getPlayerState().getSpawnCoordinates()[1]);
...