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

Testing request with CSRF Token in Play framework 2.5 (Scala)

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

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

java.lang.RuntimeException: No CSRF token present!

我在路由中使用 FakeRequest 以测试它们:

val fakeRequest   = FakeRequest(GET, s"/backOffice/login")
val Some(result)  = route(app, fakeRequest)

如何添加 CRSF 令牌才能使我的测试再次成功?

(谢谢,抱歉英语不好,我不是母语)

更新:就像 haui 在他的评论中所说的那样:

Seems like they added something similar in play version 2.6. There you can use import play.api.test.CSRFTokenHelper._ FakeRequest().withCSRFToken (Scala) and CSRFTokenHelper.addCSRFToken(requestBuilder) (Java) as explained in the Migration guide

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

所以,在查看 Play-scala classes 一段时间后,我终于找到了一种方法来调整这个答案: 到 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))
  }
}

要使用它,只需用它扩展您的测试 class,就像这样:

class LoginSpec extends PlaySpec with OneAppPerSuite /* or whatever OneApp */ with CSRFTest

然后,而不是调用

val fakeRequest = FakeRequest(/* params */)

直接打电话

val fakeRequest = addToken(FakeRequest(/* params */))

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