2012-03-26 12 views
5

Ich suche nach einer Möglichkeit, die Sitzung bei der Verwendung von Play 2.0's fakeRequest in meinen Java-Tests beizubehalten, aber meine Versuche scheitern beim Aufruf von Methoden im Scala-basierten Modus JARs.Sitzung in nachfolgenden Java-Aufrufen von Play 2.0 halten fakeRequest

Auf der Grundlage einer Anfrage Zug in der Frage Add values to Session during testing (FakeRequest, FakeApplication) Scala erwähnt, dachte ich, das folgende könnte in Java arbeiten:

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

Dies kompiliert ganz gut, aber während der Durchführung der Tests wird es mir:

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

Als eine komplette Scala Newby habe ich wirklich keine Ahnung, ob ich überhaupt in der Nähe bin. Die Scala Sitzung does expose (trait) that method through CookieBaker, I denken.

Beachten Sie, dass ich nicht unbedingt nach einer Möglichkeit suche, den oben genannten Code zu erhalten; Das obige ist wirklich nur der erste (mögliche) Schritt, um die Sitzung zu bekommen. Als nächstes würde ich wahrscheinlich versuchen, etwas wie play.api.mvc.Session.encodeAsCookie(session) zu verwenden, um es an die nachfolgenden Anforderungen zu übergeben. Wie für 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 
    } 
    }); 
} 

Für 1.x Playframework Secure module: how do you “log in” to test a secured controller in a FunctionalTest? hilft, aber die Dinge scheinen zu haben in 2.0 geändert, und ich habe nie 1.x verwendet

+0

(addierte auch auf [einem verwandten Beitrag in der Play-Framework Google-Gruppe] (https://groups.google.com/forum/#!searchin/play-framework/session/play-framework/FuXaP7z9wz8) (Warten auf Moderation. Wird dies gegebenenfalls mit diesem Post synchronisieren.) – Arjan

+0

In Google Groups hat Peter Hausel gerade geschrieben: * Hi, ich werde heute (neben Cookie und Flash-Unterstützung) eine Lösung dafür bereitstellen. Danke Peter * – Arjan

Antwort

6

Nicht viel Magie benötigt doch. Die folgende einfach bewahrt die HTTP-Header, die Cookies setzen, und übergibt das in der nächsten Anfrage.

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

(Siehe the first version diese sehr Antwort für einige Informationen über das Erhalten nur die PLAY_SESSION Cookie, und das Parsen Das ist kaum benötigt aber.)

+0

Vielen Dank für diese Antwort. – Mikesname

3

Es ist wirklich einfach mit der aktuellen Version von Play, die Sitzung in Ihren Tests zu verwenden. Sie können die statische Hilfsmethode cookies(Result result) verwenden.

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