在Play框架2.5(Scala)中使用CSRF令牌进行测试请求

Arg*_*rth 9 unit-testing scala playframework playframework-2.5

我的功能测试遇到了一个小问题.

我玩了!2.5 scala项目,其中我在某些表单上添加了CSRF验证,相关的scala-test单元测试失败,正如预期的那样,错误:

java.lang.RuntimeException: No CSRF token present!
Run Code Online (Sandbox Code Playgroud)

我正在使用FakeRequest和路由来测试它们:

val fakeRequest   = FakeRequest(GET, s"/backOffice/login")
val Some(result)  = route(app, fakeRequest)
Run Code Online (Sandbox Code Playgroud)

我怎样才能添加CRSF令牌以使我的测试再次成功?

(谢谢你,抱歉英语不好,我不是本地人)

Arg*_*rth 8

更新:像haui在评论中所说:

似乎他们在游戏版本2.6中添加了类似的东西.在那里,您可以使用import play.api.test.CSRFTokenHelper._ FakeRequest().withCSRFToken(Scala)和CSRFTokenHelper.addCSRFToken(requestBuilder)(Java),如迁移指南中所述

对于仍然在2.5.6的人,我的答案仍然适用:

所以,在看了Play-scala课程一段时间之后,我终于找到了一种方法来适应这个答案:https://stackoverflow.com/a/19849420/4496364 to Play 2.5.6

我甚至做了一个特性,所以如果有人需要它,有一天,这里是:

import play.api.Application
import play.api.test.FakeRequest
import play.filters.csrf.CSRF.Token
import play.filters.csrf.{CSRFConfigProvider, CSRFFilter}

import scala.language.postfixOps

trait CSRFTest {
  def addToken[T](fakeRequest: FakeRequest[T])(implicit app: Application) = {
    val csrfConfig     = app.injector.instanceOf[CSRFConfigProvider].get
    val csrfFilter     = app.injector.instanceOf[CSRFFilter]
    val token          = csrfFilter.tokenProvider.generateToken

    fakeRequest.copyFakeRequest(tags = fakeRequest.tags ++ Map(
      Token.NameRequestTag  -> csrfConfig.tokenName,
      Token.RequestTag      -> token
    )).withHeaders((csrfConfig.headerName, token))
  }
}
Run Code Online (Sandbox Code Playgroud)

要使用它,只需使用它扩展您的测试类,如下所示:

class LoginSpec extends PlaySpec with OneAppPerSuite /* or whatever OneApp */ with CSRFTest
Run Code Online (Sandbox Code Playgroud)

然后,而不是打电话

val fakeRequest = FakeRequest(/* params */)
Run Code Online (Sandbox Code Playgroud)

简单地打电话

val fakeRequest = addToken(FakeRequest(/* params */))
Run Code Online (Sandbox Code Playgroud)

我试着让它看起来像控制器中的addToken {} :)

  • 似乎他们在游戏版本2.6中添加了类似的东西.在那里你可以使用`FakeRequest().withCSRFToken`(Scala)和`CSRFTokenHelper.addCSRFToken(requestBuilder)`(Java),如[迁移指南]中所述(https://www.playframework.com/documentation/2.6.x/Migration26#测试与 - csrffilter) (3认同)