Playframework安全模块:您如何"登录"以测试FunctionalTest中的安全控制器?

Mar*_*k S 17 playframework

编辑:我正在使用Play!1.2版(生产版)

我想测试由安全模块类保护的控制器操作,因此我需要在测试我的控制器之前登录(否则我将被重定向到登录页面).

我在调用安全操作之前尝试登录.这是我的FunctionalTest的样子:

@Test
public void someTestOfASecuredAction() {
    Map<String, String> loginUserParams = new HashMap<String, String>(); 
    loginUserParams.put("username", "admin"); 
    loginUserParams.put("password", "admin");

    // Login here so the following request will be authenticated:
    Response response = POST("/login", loginUserParams);

    // The following is an action that requires an authenticated user:
    Map<String, String> params;
    params.put("someparam", "somevalue");
    response = POST("/some/secured/action", params);

    assertIsOk(response); // this always fails because it is a 302 redirecting to /login
}
Run Code Online (Sandbox Code Playgroud)

单步执行代码,我已经验证登录帖子是否有效 - 它会导致重定向响应,并将位置设置为主页(表示登录成功).

但随后在随后的安全行动调用中,我总是被重定向到"/ login"页面 - 表明我之前的登录没有坚持第二个POST请求.

查看FunctionalTest的源代码,我看到有一个@Before拦截器可以清除所有cookie.我尝试在我自己的中间超类中覆盖此截取(以保留cookie),但这也不起作用.

编辑:我把play.mvc.Before拦截器与org.junit.Before混淆了 - 前者用于Play!控制器,后者用于JUnit测试.FuncitonTest中的@Before是一个JUnit拦截器,所以它应该对cookie有任何影响(因为它在运行测试之前运行一次).

我不想为每个安全行动编写Selenium测试 - 因为几乎所有操作都是安全的.有没有办法"欺骗"安全模块,使其相信您已通过身份验证?或者也许是其他一些非常明显的方法来处理FunctionalTest中的这个(看似常见的)场景?

提前致谢,

标记

编辑:工作代码,Codemwnci的答案标记为正确

Codemwnci的答案是正确的.以下是我将Cookie从一个请求保留到下一个请求的解决方法:

@Test
public void someTestOfASecuredAction() {
    Map<String, String> loginUserParams = new HashMap<String, String>();
    loginUserParams.put("username", "admin");
    loginUserParams.put("password", "admin");
    Response loginResponse = POST("/login", loginUserParams);

    Request request = newRequest();
    request.cookies = loginResponse.cookies; // this makes the request authenticated
    request.url = "/some/secured/action";
    request.method = "POST";
    request.params.put("someparam", "somevalue");
    Response response = makeRequest(request);
    assertIsOk(response); // Passes!
}
Run Code Online (Sandbox Code Playgroud)

Cod*_*nci 7

我认为肯定会对@Before拦截器的作用产生误解.它在执行测试之前执行.如果您的测试然后将您登录,则此事件在@Before代码执行后发生,并且安全模块的结果应保存到Cookie.

因此,我只能假设Cookie没有发送以下请求,因此,我建议尝试以下...

在您登录后立即从Response对象获取安全cookie使用的cookie.创建一个Request对象并将Cookie设置为请求对象,然后调用您的POST方法,传入您的请求对象.

我没有测试过这段代码,所以不确定它是如何对混合预先构建的请求对象和传入URL做出反应,但不确定还有什么建议.