6

我想为我的控制器编写测试:

Result changeAction = callAction(controllers.routes.ref.Users.changePassword());
assertThat(status(changeAction)).isEqualTo(OK);

我有一个 http 状态码 - 300。

没错,它是重定向,因为我有一个名为 Secured 的类

package controllers;

import play.mvc.*;
import play.mvc.Http.*;

public class Secured extends Security.Authenticator {

    @Override
    public String getUsername(Context ctx) {
        return ctx.session().get("userId");
    }

    @Override
    public Result onUnauthorized(Context ctx) {
        return redirect(routes.Users.login(ctx.request().uri()));
    }


}

当我使用@Security.Authenticated(Secured.class)控制器方法的注释时,如果与“userId”的会话不存在,它会重定向。

所以问题是,我怎样才能伪造会话?

我试过显然打电话Controller.session("usderId", "2");

并得到了一个例外:

java.lang.RuntimeException: There is no HTTP Context available from here.

    at play.mvc.Http$Context.current(Http.java:30)
    at play.mvc.Controller.session(Controller.java:54)
    at play.mvc.Controller.session(Controller.java:61)
    at controllers.UsersTest.testUnloginedChangePassword(UsersTest.java:35)

我的问题是:如何伪造控制器的会话?

还有一个问题:如何在不使用已弃用 API 的情况下测试路由,例如Result result = routeAndCall(fakeRequest(GET, "/change_password"));

4

1 回答 1

6

你可以使用 的withSession(String, String)方法fakeRequest把东西放在 Session 中。请注意,这会返回 a fakeRequest,因此如果您需要在会话中放置多个键,则可以链接该方法。

您的测试可能看起来像这样:

@Test
public void test() {
   running(fakeApplication(), new Runnable() {
       public void run() {
           String username = "Aerus";
           Result res = route(fakeRequest("GET", "/")
                            .withSession("username", username)
                            .withSession("key","value"));
           assert(contentAsString(res).contains(username));
       }
   });
}

另请注意,我使用的是route方法而不是routeAndCall,首先是替换不推荐使用的方法。

于 2013-06-09T11:17:55.500 回答