【问题标题】:Keep session in subsequent Java calls to Play 2.0's fakeRequest在对 Play 2.0 的 fakeRequest 的后续 Java 调用中保持会话
【发布时间】:2014-06-21 05:37:28
【问题描述】:

我正在寻找一种在我的 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。

【问题讨论】:

  • (也添加到a related post in the Play Framework Google group;等待审核。如果适用,将与此帖子保持同步。)
  • 在 Google 网上论坛中,Peter Hausel 刚刚写道:您好,我今天将对此进行修复(以及 cookie 和 flash 支持)。谢谢彼得

标签: java scala interop playframework-2.0


【解决方案1】:

毕竟不需要太多魔法。以下只是保留设置 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"));

(有关仅获取 PLAY_SESSION cookie 并对其进行解析的一些信息,请参阅此答案的 the first version。不过,这几乎不需要。)

【讨论】:

  • 非常感谢您的回答。
【解决方案2】:

使用当前版本的 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);

【讨论】:

    猜你喜欢
    • 2012-06-09
    • 2021-07-31
    • 2019-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    • 2011-03-09
    相关资源
    最近更新 更多