函数的模拟函数参数
问题描述:
我正在使用Scala,Play Framework开发web应用程序。我需要用自定义操作来测试控制器。请看代码:函数的模拟函数参数
package controllers.helpers
import play.api.mvc.{ActionBuilder, Request, Result}
import scala.concurrent.Future
class CustomAction extends ActionBuilder[Request] {
override def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[Result]): Future[Result] = {
// do some stuff
block(request)
}
}
package controllers
import javax.inject.Singleton
import play.api.mvc.Controller
@Singleton
class SomeController @Inject() (customAction: CustomAction
) extends Controller {
def foo() = customAction(parse.json) { implicit request =>
// do some stuff and create result
}
}
下面你可以找到测试类的代码。我用Specs2和我上线了org.mockito.exceptions.misusing.InvalidUseOfMatchersException
与customeActionMock.invokeBlock(any[Request[_]], any[(Request[_]) => Future[Result]]) returns mock[Future[Result]]
package controllers
import controllers.helpers.CustomAction
import org.specs2.mock.Mockito
import play.api.mvc.{Request, Result}
import play.api.test.{FakeHeaders, FakeRequest, PlaySpecification}
import scala.concurrent.Future
class SomeControllerSpec extends PlaySpecification with Mockito {
private val customeActionMock = mock[CustomAction]
customeActionMock.invokeBlock(any[Request[_]], any[(Request[_]) => Future[Result]]) returns mock[Future[Result]] //this doesn't work, exception is thrown there
"SomController" should {
"respond Ok on valid request" in {
val result = new UserController(customeActionMock).foo()(FakeRequest())
status(result) shouldEqual OK
}
}
}
我明白,我嘲笑CustomAction
正确的block
参数。有人可以帮助我做到这一点吗?
答
不要嘲笑CustomAction:
class SomeControllerSpec extends PlaySpecification with Mockito {
private val customeActionMock = new CustomAction
"SomController" should {
"respond Ok on valid request" in {
val result = new UserController(customeActionMock).foo()(FakeRequest())
status(result) shouldEqual OK
}
}
}
答
我的项目使用播放2.5.x.我使用scalatest。这是我如何测试控制器。
import org.scalatestplus.play.OneAppPerSuite
import org.scalatest._
import org.scalatest.time.{Millis, Seconds, Span}
import org.scalatest.concurrent.ScalaFutures
import scala.concurrent.Future
class SomeControllerSpec extends FlatSpec with Matchers with ScalaFutures with OneAppPerSuite {
private val customeActionMock = new CustomAction // create an instance of a class
implicit val defaultPatience = PatienceConfig(timeout = Span(5,Seconds), interval = Span(500, Millis))
it should "respond Ok on valid request" in {
val resultF : Future[Result] = new UserController(customeActionMock).foo()(FakeRequest())
whenReady(resultF) { resultR =>
resultR.header.status shouldBe 200
}
}
}
+0
我正在使用2.6并启用了播放缓存。我花了3个小时试图嘲笑这个实现。我结束了为测试创建自己的缓存类,因为我得到了同样的错误。拇指向下播放Play2。谢谢@ecamur。 –
您设置您的测试的方式,结果值''会保留模拟值'mock [Future [Result]]''。换句话说,如果你嘲笑应该运行'block'的代码,你的行为中的代码将不会运行..我想我不会模仿CustomAction,但是它会成为测试的一部分。 – rethab