繁体   English   中英

如何在集成测试中执行此控制器操作代码?

[英]How can I execute this controller action code in an integration test?

我正在使用Scala Play框架编写集成测试。

我在控制器中有一个看起来像这样的函数:

def myEndpoint: AnyAction = myActionProvider.securedEndpoint("myEndpoint") { implicit request =>
    // Business logic
    Ok("")
}

myActionProvider.securedEndpoint链结合在一起的一些行动建设者使用andThen()并返回一个ActionBuilder

在集成测试中,我具有以下几点:

val fakeRequest: FakeRequest = buildFakeRequest()
myController.myEndpoint.apply(fakeRequest)

虚假请求包含生成的安全令牌和我们的应用程序所需的其他标头。

我能够在myActionProvider.securedEndpoint内进行破解并遵循执行。 但是,我无法在任何invokeBlock方法内或控制器的业务逻辑内进行破解。 记录显示这些路径从未执行。

如果将myController.myEndpoint.apply(fakeRequest)的结果保存到变量中,则其类型为Accumulator[ByteString, Result] 看起来它包含链接的Action构建器和业务逻辑代码块,但Play从未执行它。

该代码不会引发任何异常,并且不会向控制台输出任何内容。

我想知道我的测试语法是否有错误。 我也尝试了以下方法,但无济于事:

  • myController.myEndpoint { fakeRequest }
  • myController.myEndpoint()(fakeRequest)

是的,代码可以在“常规”(例如非测试环境)下工作:)

我在这里创建了一个有关如何测试Controller的工作示例。 它基于带有Guice的Play 2.6.15,并使用scalatestplus-play库。

libraryDependencies ++= Seq(
  "org.scalatestplus.play" %% "scalatestplus-play" % "3.1.2" % "test"
)

这是一个有两个动作的控制器:

import javax.inject.Inject
import play.api.mvc._

class ApplicationController @Inject()(controllerComponents: ControllerComponents)
  extends AbstractController(controllerComponents) {

  def foo(): Action[AnyContent] = Action { request =>
    Ok(s"I am listening at ${request.uri}")
  }

  def bar: Action[String] = Action(parse.tolerantText) { request =>
    Ok(s"Received body of size: ${request.body.length}")
  }
}

具有显式主体解析器的操作确实确实会返回一个Accumulator对象。 有趣的是,具有默认主体解析器的操作将返回Future

但是,在这两种情况下, play-test库都提供了用于从两种类型的结果中提取结果正文,状态和其他内容的助手。

import akka.stream.Materializer
import akka.util.ByteString
import org.scalatestplus.play._
import play.api.http.Status
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.libs.streams.Accumulator
import play.api.mvc._
import play.api.test.Helpers._
import play.api.test._

import scala.concurrent.Future

class ApplicationControllerTest extends PlaySpec {

  "ApplicationController" should {

    val application = new GuiceApplicationBuilder().build()
    val controller = application.injector.instanceOf[ApplicationController]

    "return correct response for foo" in {
      val result: Future[Result] = controller.foo().apply(FakeRequest("GET", "/testUriFoo"))
      contentAsString(result) mustBe "I am listening at /testUriFoo"
      status(result) mustBe Status.OK
    }

    "return correct response for bar" in {
      implicit val mat: Materializer = application.materializer
      val fakeRequest = FakeRequest("POST", "/testUriBar").withTextBody("123456789")
      val result: Accumulator[ByteString, Result] = controller.bar().apply(fakeRequest)
      contentAsString(result) mustBe "Received body of size: 9"
      status(result) mustBe Status.OK
    }

  }

}

使用的资源:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM