2012-03-26 23 views
5

Szukam sposobu, aby zachować sesję podczas korzystania z fakeRequest Play 2.0 w moich testach Java, ale moje próby zawiodły podczas wywoływania metod w oparciu o Scala JAR.Zatrzymaj sesję w kolejnych wywołaniach Java do fakeRequest Play 2.0

podstawie wniosku ciągnącej wymienionego w pytaniu Scala Add values to Session during testing (FakeRequest, FakeApplication), pomyślałem następujące może pracować w Javie:

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

To kompiluje dobrze, ale podczas uruchamiania testów robi mnie:

java.lang.NoSuchMethodError: 
    play.api.mvc.Session.decodeFromCookie(Lscala/Option;)Lplay/api/mvc/Session; 

Będąc w sumie Scala newby, naprawdę nie mam pojęcia, czy jestem nawet blisko. Sesja Scala does expose (trait) that method through CookieBaker, I wymyślić.

Zauważ, że niekoniecznie szukam sposobu na uruchomienie powyższego kodu; powyższe jest naprawdę tylko pierwszym (możliwym) krokiem do uzyskania sesji. Następnie prawdopodobnie spróbuję użyć czegoś takiego, jak play.api.mvc.Session.encodeAsCookie(session), aby przekazać je kolejnym żądaniom. Jak dla 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 
    } 
    }); 
} 

Dla 1.x, Playframework Secure module: how do you “log in” to test a secured controller in a FunctionalTest? pomaga, ale wszystko wydaje się, że zmienił się w 2,0, a ja nigdy nie używane 1.x.

+0

(Dodano także opcję [pokrewnym stanowisku w play ramowego grupy Google] (https://groups.google.com/forum/#!searchin/play-framework/session/play-framework/FuXaP7z9wz8) , Oczekując na moderację, zachowa synchronizację z tym wpisem, jeśli dotyczy.) – Arjan

+0

W Google Groups, Peter Hausel napisał: * Cześć, zamierzam dzisiaj wprowadzić poprawkę (wraz z obsługą plików cookie i flash). Dzięki peter * – Arjan

Odpowiedz

6

Niezbyt dużo magii potrzebnej. Następujący po prostu zachowuje nagłówek HTTP, który ustawia cookie i przekazuje, że w następnym żądaniu.

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

(Zobacz the first version tej samej odpowiedzi na pewne informacje na temat uzyskiwania tylko PLAY_SESSION cookie i analizowania, że ​​to mało potrzebne).

+0

Bardzo dziękuję za tę odpowiedź. – Mikesname

3

To bardzo proste, ponieważ obecna wersja gry używa sesji w twoich testach. Możesz użyć statycznej metody pomocniczej 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); 
Powiązane problemy