我正在寻找一种在我的Java测试中使用Play 2.0的fakeRequest时保留会话的方法,但是在基于Scala的JAR中调用方法时我的尝试失败了。
根据Scala问题Add values to Session during testing (FakeRequest, FakeApplication)中提到的拉取请求,我认为以下内容可能适用于Java:
public Session getSession(Result result) {
play.api.mvc.Cookies scalaCookies =
play.api.test.Helpers.cookies(result.getWrappedResult());
play.api.mvc.Cookie scalaSessionCookie =
scalaCookies.get(play.api.mvc.Session.COOKIE_NAME()).get();
scala.Option<play.api.mvc.Cookie> optionalCookie =
scala.Option.apply(scalaSessionCookie);
// Compiles fine, but fails with NoSuchMethodError:
play.api.mvc.Session scalaSession =
play.api.mvc.Session.decodeFromCookie(optionalCookie);
return new play.mvc.Http.Session(Scala.asJava(scalaSession.data()));
}
这编译得很好,但在运行测试时它会让我:
java.lang.NoSuchMethodError:
play.api.mvc.Session.decodeFromCookie(Lscala/Option;)Lplay/api/mvc/Session;
作为一个新的Scala,我真的不知道我是否接近。 Scala会话does expose (trait) that method through CookieBaker,我认为。
请注意,我不一定要找到一种方法来运行上面的代码;以上只是获得会议的第一步(可能)。接下来,我可能会尝试使用类似play.api.mvc.Session.encodeAsCookie(session)
的内容将其传递给后续请求。与the ZenTasks demo相似:
@Test
public void testLoginAndMore() {
Helpers.running(Helpers.fakeApplication(Helpers.inMemoryDatabase()),
new Runnable() {
public void run() {
Map<String, String> data = new HashMap<String, String>();
data.put("email", "guillaume@sample.com");
data.put("password", "secret");
Result result =
callAction(controllers.routes.ref.Application.authenticate(),
fakeRequest().withFormUrlEncodedBody(data));
assertThat(status(result)).isEqualTo(Status.SEE_OTHER);
assertThat(redirectLocation(result)).isEqualTo("/");
// All fine; we're logged in. Now somehow preserve the cookie. This
// does NOT do the trick:
Session session = getSession(result);
// ...subsequent callAction(..)s, somehow passing the session cookie
}
});
}
对于1.x,Playframework Secure module: how do you “log in” to test a secured controller in a FunctionalTest?会有所帮助,但事情似乎在2.0中发生了变化,我从未使用过1.x。
答案 0 :(得分:6)
毕竟不需要太大的魔力。以下简单地保留了设置cookie的HTTP头,并在下一个请求中传递它:
Map<String, String> data = new HashMap<String, String>();
data.put("email", "guillaume@sample.com");
data.put("password", "secret");
Result result = callAction(controllers.routes.ref.Application.authenticate(),
fakeRequest().withFormUrlEncodedBody(data));
assertThat(status(result)).isEqualTo(Status.SEE_OTHER);
assertThat(redirectLocation(result)).isEqualTo("/");
// All fine; we're logged in. Preserve the cookies:
String cookies = header(HeaderNames.SET_COOKIE, result);
// Fetch next page, passing the cookies
result = routeAndCall(fakeRequest(GET, redirectLocation(result))
.withHeader(HeaderNames.COOKIE, cookies));
assertThat(status(result)).isEqualTo(Status.OK);
assertThat(contentAsString(result).contains("Guillaume Bort"));
(请参阅这个答案的the first version,了解有关仅获取PLAY_SESSION
cookie并解析它的一些信息。但这几乎不需要。)
答案 1 :(得分:3)
使用当前版本的Play在测试中使用会话非常容易。您可以使用cookies(Result result)
静态助手方法。
// Route that sets some session data to be used in subsequent requests
Result result = callAction(...);
Http.Cookie[] cookies = FluentIterable.from(cookies(result)).toArray(Http.Cookie.class);
FakeRequest request = new FakeRequest(GET, "/someRoute").withCookies(cookies);
callAction(controllers.routes.ref.Application.requestNeedingSession(), request);