I am trying to test my Play Application controller, but am struggling to find away to have the test return both session data while utilising an instance of the controller.
public class HomeControllerTest extends WithApplication {
@Override
protected Application provideApplication() {
return new GuiceApplicationBuilder()
.configure("play.http.router", "router.Routes")
.build();
}
@Test
public void testGameChoiceHvH() {
Map form = new HashMap<String, String>();
form.put("gameType", "0");
HomeController homeController = new HomeController();
Result result = invokeWithContext(fakeRequest().bodyForm(form),
() -> homeController.chooseGame());
assertEquals(SEE_OTHER, result.status());
assertEquals("/play", result.header("Location").get());
assertFalse(result.session().isEmpty());
String gameId = result.session().get("game_id");
assertTrue(homeController.getGame(gameId).getCurrentPlayer() instanceof Human);
}
}
The final assertion here is simulating taking the gameId stored in the session and using it retrieve the game instance, created in the controller action and stored in a Map within the controller instance. The issue is that by using invokeWithContext, the result does not contain the Cookie object at all, so it cannot be retrieved.
The alternative method I have found to create a post request is the following:
public class HomeControllerTest extends WithApplication {
@Override
protected Application provideApplication() {
return new GuiceApplicationBuilder()
.configure("play.http.router", "router.Routes")
.build();
}
@Test
public void testGameChoiceHvH() {
Map form = new HashMap<String, String>();
form.put("gameType", "0");
HomeController homeController = new HomeController();
Result result = route(fakeRequest(routes.HomeController.chooseGame()).bodyForm(form));
assertEquals(SEE_OTHER, result.status());
assertEquals("/play", result.header("Location").get());
assertFalse(result.session().isEmpty());
String gameId = result.session().get("game_id");
assertTrue(homeController.getGame(gameId).getCurrentPlayer() instanceof Human);
}
}
However, this obviously means that the final assertion is looking at a new instance of the HomeController, not the one used by the route function, so as such, the Map is empty.
For clarity, here is the relevant controller code:
public class HomeController extends Controller {
private WebInterface ui = new WebInterface();
private Map<String, Board> boardMap = new HashMap<>();
private Map<String, Game> gameMap = new HashMap<>();
public Game getGame(String gameId) {
return gameMap.get(gameId);
}
public Result chooseGame() {
Map<String, String[]> request = request().body().asFormUrlEncoded();
Board board = new Board();
Game game = new Game(new PlayerFactory(ui).create(GameType.values()[Integer.valueOf(request.get("gameType")[0])]));
boardMap.put(Integer.toString(board.hashCode()), board);
gameMap.put(Integer.toString(game.hashCode()), game);
session("game_id", Integer.toString(game.hashCode()));
session("board_id", Integer.toString(board.hashCode()));
return redirect("/play");
}
Any help would be much appreciated.
Aucun commentaire:
Enregistrer un commentaire