Search code examples
javajunit5fxgl

Testing a FXGL game


I'm programming a simple game in Java FXGL. I'm very new to Java FX and FXGL.

I'd like to test my game with JUnit5, but I can't get it to work... The problem: When I launch my tests, the FXGL properties aren't initialized yet.

I would be very happy if someone can give me an idea, how to launch a test for a class witch is using the FXGL.getWorldProperties()

My class:

public class Player {

    private int playerColumn = 2;   // The actual column from the player
    private int nColumns;     // Numbers of Columns in the game // Will be set on the init of the game

    public int getPlayerColumn() {
        return playerColumn;
    }

    // Some more code ...

    /**
     * The Input Handler for moving the Player to the right
     */
    public void moveRight() {
        if (playerColumn < nColumns - 1) {
            playerColumn++;
        }
        updatePlayerPosition();
    }


    /**
     * Calculates the x Offset for the Player from the column
     */
    private void updatePlayerPosition() {
        getWorldProperties().setValue("playerX", calcXOffset(playerColumn, playerFactory.getWidth()));
    }

    // Some more code ...

}

My Test Class: I have no idea how I could do it...

@ExtendWith(RunWithFX.class)
public class PlayerTest{

  private final GameArea gameArea = new GameArea(800, 900, 560, 90);
  private final int nColumns = 4; // Numbers of Columns in the game


  @BeforeAll
  public static void init(){
    Main.main(null);
  }

  @Test
  public void playerColumn_init(){
    Player player = new Player();
    assertEquals(2, player.getPlayerColumn());
  }

  @Test
  public void moveLeft_2to1(){
    Player player = new Player();
    player.moveLeft();
    assertEquals(1, player.getPlayerColumn());
  }
}

In this scenario the test don't launch at all, because the program is traped in the game loop... But if i let the Main.main(null); - call away, the proberties arn't initialized


Solution

  • Generally, you have two options:

    1. This is the recommended approach as I assume you want to unit test your own code. FXGL.getWorldProperties() returns a PropertyMap. Instead of having an internal dependency on FXGL.getWorldProperties(), you could make your Player class depend on PropertyMap instead. For example:
    class Player {
        private PropertyMap map;
    
        public Player(PropertyMap map) {
            this.map = map;
        }
    }
    
    // production code
    var player = new Player(FXGL.getWorldProperties());
    
    // test code
    var player = new Player(new PropertyMap());
    
    1. This is not recommended, though it can work as an integration test. Launch the entire game with GameApplication.launch(YourApp.class) in a different thread (it will block until game finishes). Then test your game normally with @Test.