模拟函数

时间:2017-02-26 13:48:22

标签: scala unit-testing playframework mockito specs2

我正在使用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
    }
  }
}

我理解我错误地模仿block的{​​{1}}参数。有人可以帮我正确地做到吗?

2 个答案:

答案 0 :(得分:1)

我的项目使用Play 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
    }
  }
}

答案 1 :(得分:0)

不要模拟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
    }
  }
}