mardi 27 octobre 2015

Play route/Controller just for unit test

I have a method that takes a Play Http.Context and "does some stuff" with the session. I want to write a unit test for just that method. Specifically, I want to test that if a request comes in with certain headers my method works correctly. It seems like the easiest way to do that reliably is to create a FakeApplication and a Controller for my test. Then I'd use Helpers.fakeRequest to get a request and Helpers.route to route that request to my controller. The controller would call my method, set some variables, etc. and I could then assert success and such.

Seems like a splendid plan but I can't figure out how to add a route to my controller in the FakeApplication. Note that this controller isn't really part of my app - it's just something I want to use for this one test. So I want to define it and construct in just this one unit test; I don't want to add it to my conf/routes file.

Specifically, I want something like this:

// Maybe I can use GlobalSettings.onRouteRequest but the return type
// is play.api.mvc.Handler which seems inaccessible from Java
FakeApplication app = Helpers.fakeApplication(new MyGlobalSettings());
Http.Request request = Helpers.fakeRequest().withCookies(...).withBody(...);
Controller testContoller = new MyTestController();
// This doesn't exist, but I want something like this
app.addRoute("/foo", ctx -> testController.method(ctx));
running(app, () -> {
    Helpers.route("/foo");
    assertThat(testContoller.itWorked()).isTrue();
}

I'm running Play 2.2.3 and writing in Java, not Scala.

I do realize I can construct an Http.Context directly and pass that to my method. However, this isn't my preferred approach for a few reasons:

  • The Http.Context constructor takes the plain text of the session variables. I want to test that things work correctly when the request contains the encrypted session cookie.
  • The Http.Context constructor is poorly documented and seems a bit off. For example, you can pass an Http.Request to the constructor, but you also pass the cookie data and session data. So what happens to the cookie/session data on the request? Does it get merged with the other data passed? Ignored?
  • It feels more "black box" to send in a request and ensure things work rather than try to figure out how this particular version of Play converts my request it an Http.Context (e.g manually constructing a context seems more likely to break with new versions of play).

Any ideas?

Aucun commentaire:

Enregistrer un commentaire