2012-03-26 54 views
5

我正在尋找一種方法來保留在我的Java測試中使用Play 2.0的fakeRequest會話,但我的嘗試失敗,同時調用基於Scala的方法JAR文件。保留會話在隨後的Java調用播放2.0的fakeRequest

根據在斯卡拉問題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 newby,我真的不知道我是否接近。斯卡拉會議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", "[email protected]"); 
     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

(也添加到[播放框架谷歌組相關的職位(https://groups.google.com/forum/#!searchin/play-framework/session/play-framework/FuXaP7z9wz8) ;等待審覈,如果可以的話,將保持與這篇文章同步。) – Arjan 2012-03-26 20:23:35

+0

在Google Groups中,Peter Hausel剛剛寫道:*嗨,我今天將推出一個修復程序(與cookie和flash支持一起)。感謝彼得* – Arjan 2012-03-28 12:07:18

回答

6

畢竟沒什麼魔法需要。下面簡單地保留了HTTP頭,設置餅乾,並將在未來的要求:

Map<String, String> data = new HashMap<String, String>(); 
data.put("email", "[email protected]"); 
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這是很難)

+0

非常感謝這個答案。 – Mikesname 2012-10-22 14:06:18

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);