无法模拟play api请求

时间:2019-07-09 17:01:12

标签: scala playframework mockito playframework-2.0 playframework-2.3

我有一个类,它接收Option[Request[_]]作为隐式(play.api.mvc.Request):

class MyClass @Inject()(...)(implicit val request: Option[Request[_]]) { ...

我的问题是在我使用play.api.test.inject之类的测试即时通讯中

  val myClass: MyClass = inject[MyClass]

并且为了能够在我的测试中做到这一点,我必须隐式提出此请求。所以我做的方法就是像这样使用mockito.ArgumentMatchers

  implicit val origReq: Option[Request[_]] = any[Option[Request[_]]]

但是当我运行测试时,出现此错误:

An exception or error caused a run to abort: Guice configuration errors:

1) No implementation for scala.Option<play.api.mvc.Request<?>> was bound.
  while locating scala.Option<play.api.mvc.Request<?>>
    for the 3rd parameter of streams.MyClass.<init>(MyClass.scala:16)
  while locating streams.MyClass

1 error 
com.google.inject.ConfigurationException: Guice configuration errors:

1) No implementation for scala.Option<play.api.mvc.Request<?>> was bound.
  while locating scala.Option<play.api.mvc.Request<?>>
    for the 3rd parameter of streams.MyClass.<init>(MyClass.scala:16)
  while locating streams.MyClass

我在做什么错? :/

1 个答案:

答案 0 :(得分:0)

问题是您正在定义一个本应由guice实例化的类,该类需要一个可选请求,很可能您需要将此请求实际进行请求范围(每个请求中都有一个不同的对象),玩起来并不简单。

我不知道inject[MyClass]的行为,我猜它不会在范围内寻找隐式的可选请求,但是它将尝试使用可用的模块实例化MyClass(仅在时间绑定是不够的,因为Request[_]并不具体,您可以通过为测试定义特定的绑定来使测试通过,但是要使应用正常运行并不容易),无论如何,提供具有泛型类型的对象并不是那么简单,因为单个Request[_]有许多可能的实现,请考虑将_替换为IntString等。

一个好主意是重构MyClass以在每个方法上都要求隐式请求,从而解决有问题的配置。

如果您仍然想在构造函数上使用隐式请求,则需要在播放时查看请求范围的绑定,这本身就是一个主题。