Scala 如何在Play框架测试中注入ExecutionContext?
我想为我的Play Framework应用程序创建测试,并继续获得Scala 如何在Play框架测试中注入ExecutionContext?,scala,playframework,playframework-2.0,guice,scalatest,Scala,Playframework,Playframework 2.0,Guice,Scalatest,我想为我的Play Framework应用程序创建测试,并继续获得java.lang.RuntimeException:没有启动的应用程序。我有一个异步控制器,如下所示: class ComputerController @Inject()(computerService: ComputerService)(implicit executionContext: ExecutionContext){ def add = Action.async { Comput
java.lang.RuntimeException:没有启动的应用程序
。我有一个异步控制器,如下所示:
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()))
}
)
}
}
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 ""
}
}
}
注射的辅助特征:
trait Inject {
val injector = new GuiceApplicationBuilder()
.in(new File("conf/application.conf").
.in(Mode.Test)
.injector
}
测试是这样的:
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()))
}
)
}
}
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隐式值,并获得executionContext.global
java.lang.RuntimeException:没有启动的应用程序
- 使用OneAppPerSuite将
添加到
并获得:ComputerControllerSpec
akka.actor.OneForOneStrategy-无法初始化ExecutionContext;AsyncExecutor已关闭
- 将{中的{中的“添加新计算机”更改为{中的{并获得:
java.lang.RuntimeException:没有启动的应用程序
我真的不知道如何将隐式的
ExecutionContext
注入到我的测试中。我想您缺少了“newwithapplication()”
试试这个
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 ""
}
}
}
该测试的工作方式是:
- 使用
和MockitoSugar
前后扩展
PlaySpec
- 覆盖:
// 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() }
然后所有测试运行时都不会抛出异常。您可以使用specs2:With
Specification
中的测试,而不是PlaySpec
(使用s保留或删除所有其他),它不断抛出java.lang.RuntimeException:没有启动的应用程序
。我真的不知道如何创建该测试,或者我是否做得很好依赖项注入:/我还使用了规范2
的隐式执行环境
,并尝试了隐式执行上下文
。如果你得到了,就有了没有启动的应用程序
错误,它还会告诉您哪段代码需要一个应用程序。您设置测试的方式似乎根本不需要任何应用程序,除非您使用play的执行上下文保持器。或者您的代码中有我们看不到的其他内容。您是对的,我的测试不应该真正需要ExecutionContext,因为我模拟了ComputerService的结果。ComputerService使用ComputerDAO,ComputerDAO需要ExecutionContext对数据库执行操作,这就是为什么我从ComputerController注入它,然后隐式地将它发送到ComputerService,最后发送到ComputerDAO。最后,它是Computer的一个要求但是它没有执行任何操作。问题是当我尝试实例化它时,即使它没有被使用。