【问题标题】:Mock functional argument of the function函数的模拟函数参数
【发布时间】:2017-02-26 13:48:22
【问题描述】:

我正在使用 Scala Play Framework 开发网络应用程序。我需要使用自定义操作来测试控制器。请看一下代码:

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 参数。有人可以帮我正确地做吗?

【问题讨论】:

  • 按照您设置测试的方式,值result 将保留模拟值mock[Future[Result]]。换句话说,如果您模拟应该运行block 的代码,那么您的操作中的代码将不会运行。我想我不会模拟CustomAction,而是让它成为测试的一部分。跨度>

标签: scala unit-testing playframework mockito specs2


【解决方案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
    }
  }
}

【讨论】:

  • 我使用的是启用了播放缓存的 2.6。我花了 3 个小时尝试模拟该实现。我最终为测试创建了自己的缓存类,因为我遇到了同样的错误。大拇指向下播放 2。谢谢@ecamur。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2022-08-23
    • 2014-10-29
    • 1970-01-01
    • 2020-06-20
    • 1970-01-01
    • 2012-07-18
    • 2022-07-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多