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

问题描述 投票:7回答:1

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

我玩了! 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)

我如何添加CSRF令牌以使我的测试再次成功?

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

scala unit-testing playframework playframework-2.5
1个回答
7
投票

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

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

对于仍然在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))
  }
}

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

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

然后,而不是打电话

val fakeRequest = FakeRequest(/* params */)

简单地打电话

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

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

© www.soinside.com 2019 - 2024. All rights reserved.