Контроллер тестирования с поддельной сессией


Я хочу написать тест для моего контроллера:

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

1 6

1 ответ:

Вы можете использовать метод withSession(String, String) fakeRequest, чтобы поместить вещи в сеанс. Обратите внимание, что это возвращает 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, Первый-это замена устаревшего метода.