如何在Play Framework测试中注入ExecutionContext?

时间:2016-10-13 00:12:22

标签: scala playframework playframework-2.0 guice scalatest

我想为Play Framework应用程序创建测试,并继续获取java.lang.RuntimeException: There is no started application。我有一个像这样的异步控制器:

    class ComputerController @Inject()(computerService: ComputerService)(implicit executionContext: ExecutionContext){
      def add = Action.async {
        ComputerForm.form.bindFromRequest.fold(
          errorForm => Future.successful(Ok(errorForm.toString)),
          data => {
            val ip = data.ip
            val name = data.name
            val user = data.user
            val password = data.password
            val computer = Computer(ip,name,user,password)
            val futureTask = computerService.add(newComputer)
            futureTask.map(res => Redirect(routes.HomeController.home()))
          }
        )
      }
    }

注射的辅助特征:

    trait Inject {
      val injector = new GuiceApplicationBuilder()
        .in(new File("conf/application.conf").
        .in(Mode.Test)
        .injector
    }

测试是这样的:

    class ComputerControllerSpec extends PlaySpec with Inject with MockitoSugar with ScalaFutures {
      lazy val computerService = mock[ComputerService]
      when(computerService.add(any[Computer])) thenReturn Future.successful("Computer added")
      implicit lazy val executionContext = injector.instanceOf[ExecutionContext]
      val controller = new ComputerController(computerService)
      "Computer Controller" should {
        "add a new computer" in {
          val computer = ComputerFormData("127.0.0.1","Computer","user","password")
          val computerForm = ComputerForm.form.fill(computer)
          val result = controller.add.apply {
            FakeRequest()
              .withFormUrlEncodedBody(computerForm.data.toSeq: _*)
          }
          val bodyText = contentAsString(result)
          bodyText mustBe ""
        }
      }
    }

我也尝试过:

  • 使用ExecutionContext.global初始化executionContext隐式值并获得java.lang.RuntimeException: There is no started application

  • with OneAppPerSuite添加到ComputerControllerSpec并获得:akka.actor.OneForOneStrategy - Cannot initialize ExecutionContext; AsyncExecutor already shut down

  • 更改"add a new computer" in {的{​​{1}}并获得:"add a new computer" in new WithApplication {

我真的不知道如何在我的测试中注入隐含的java.lang.RuntimeException: There is no started application

2 个答案:

答案 0 :(得分:1)

我猜你错过了“new WithApplication()”  试试这个

class ComputerControllerSpec extends PlaySpec with Inject with MockitoSugar with ScalaFutures {
  lazy val computerService = mock[ComputerService]
  when(computerService.add(any[Computer])) thenReturn Future.successful("Computer added")
  implicit lazy val executionContext = injector.instanceOf[ExecutionContext]
  val controller = new ComputerController(computerService)
  "Computer Controller" should {
    "add a new computer" in new WithApplication() {
      val computer = ComputerFormData("127.0.0.1","Computer","user","password")
      val computerForm = ComputerForm.form.fill(computer)
      val result = controller.add.apply {
        FakeRequest()
          .withFormUrlEncodedBody(computerForm.data.toSeq: _*)
      }
      val bodyText = contentAsString(result)
      bodyText mustBe ""
    }
  }
}

答案 1 :(得分:0)

这项测试的工作方式是:

  • 使用PlaySpecMockitoSugar
  • 扩展BeforeAndAfterAll
  • 重写:

    // Before all the tests, start the fake Play application
    override def beforeAll() {
      application.startPlay()
    }
    // After the tests execution, shut down the fake application
    override def afterAll() {
      application.stopPlay()
    }
    

然后所有测试都在没有抛出异常的情况下运行。