scala - 如何在 Controller 中进行单元测试?

标签 scala specs2 playframework-2.4

假设我有如下 Controller :

class JenisKejahatanControl @Inject()(service: JenisKejahatanService, val messagesApi: MessagesApi) extends Controller with I18nSupport {

  def add = Action.async { implicit request =>
    lazy val incoming = JenisKejahatan.formJenisK.bindFromRequest()

    incoming.fold( error => {
      lazy val response = ErrorResponse(BAD_REQUEST, messagesApi("request.error"))
      Future.successful(BadRequest(Json.toJson(response)))
    }, { newJenisK =>
      lazy val future = service.addJenisK(newJenisK)
      future.flatMap {
        case Some(jenis) => Future.successful(Created(Json.toJson(SuccessResponse(jenis))))
        case None => Future.successful(BadRequest(Json.toJson(ErrorResponse(NOT_FOUND, messagesApi("add.jenis.kejahatan.fail")))))
      }
    })
  }
}

我想使用specs2测试我的def add,该怎么做?

最佳答案

由于您的 Controller 已注入(inject)组件,因此我假设您缺少的一点是如何在满足各种依赖项的规范中获取它的实例。为此,您可以使用 GuiceApplicationBuilder获取 Play 应用程序实例,然后使用其注入(inject)器 获取 Controller 的实例,而无需手动构建它(更多依赖项注入(inject)文档 here ,特别是关于使用 Guice 进行测试 here 。 )

如果您可以手动构建 Controller (如示例所示),那就太好了,并且使事情变得更简单,但是 Controller 往往具有重要的依赖项,您很可能希望使用覆盖来模拟这些依赖项GuiceApplicationBuilder 上的方法。

构建 Controller 实例后,将模拟(假)请求“应用”到您的操作方法并确定它们提供您期望的状态和主体就非常简单了。这是一个例子:

import controllers.{SuccessResponse, JenisKejahatanControl}
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.inject.bind
import play.api.mvc.Result
import play.api.test.{FakeRequest, PlaySpecification}

import scala.concurrent.Future

class JenisKejahatanControlSpec extends PlaySpecification {

  "JenisKejahatanControl#add" should {
    "be valid" in {

      // Build an instance of a Play application using the
      // default environment and configuration, and use it
      // to obtain an instance of your controller with the
      // various components injected.
      val jenisController = new GuiceApplicationBuilder()
        .overrides(  // Mock the data service
          bind[JenisKejahatanService]
           .toInstance(new MockJenisKejahatanService))
        .build()
        .injector
        .instanceOf[JenisKejahatanControl]

      // Create a "fake" request instance with the appropriate body data
      val request = FakeRequest().withFormUrlEncodedBody("name" -> "test")

      // Apply the request to your action to obtain a response
      val eventualResult: Future[Result] = jenisController.add.apply(request)

      // Check the status of the response
      status(eventualResult) must_== CREATED

      // Ensure the content of the response is as-expected
      contentAsJson(eventualResult).validate[SuccessResponse].asOpt must beSome.which { r =>
        r.jenis.name must_== "test"
      }
    }
  }
}

关于scala - 如何在 Controller 中进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34508836/

相关文章:

Scala 类型参数

scala - 在 Specs2 中使用 Akka TestKit

java - Play Framework 2.4 : NoClassDefFoundError: play/api/cache/CachePlugin

playframework - 如何覆盖 Play 的默认 Ebean 服务器配置?

scala - 使用Scala在Apache Spark中连接不同RDD的数据集

scala - 如何定义生成序列元素子集的 ScalaCheck 生成器?

scala - 在 Scala 类声明中, "with"关键字是否指定了 "is-a"关系?

unit-testing - Scala 中的 JUnit 测试类别?

scala - 如何验证异步方法中的mockito调用