如何在 Play Framework 测试中注入 ExecutionContext?
How can ExecutionContext be injected on Play Framework tests?
我想为我的 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 {
更改为 "add a new computer" in new WithApplication {
并得到:java.lang.RuntimeException: There is no started application
我真的不知道如何将隐式 ExecutionContext
注入到我的测试中。
我猜你不见了"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 ""
}
}
}
这个测试开始工作的方式是:
- 用
MockitoSugar
和 BeforeAndAfterAll
扩展 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()
}
然后所有测试 运行 都没有抛出异常。
我想为我的 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 {
更改为"add a new computer" in new WithApplication {
并得到:java.lang.RuntimeException: There is no started application
我真的不知道如何将隐式 ExecutionContext
注入到我的测试中。
我猜你不见了"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 ""
}
}
}
这个测试开始工作的方式是:
- 用
MockitoSugar
和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() }
PlaySpec
然后所有测试 运行 都没有抛出异常。