有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

scala在后续Java调用中保留会话以播放2.0的FakereRequest

我正在寻找一种在Java测试中使用Play 2.0的FakereRequest时保留会话的方法,但是在基于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。十,


共 (2) 个答案

  1. # 1 楼答案

    使用当前版本的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);
    
  2. # 2 楼答案

    毕竟不需要太多的魔法。以下仅保留设置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_SESSIONcookie并对其进行解析的一些信息,请参见本答案的the first version。不过这几乎不需要。)