Scala тестирование насмешливых неявных параметров?

Мне сложно усердно пытаться понять, как писать тесты в Scala, когда задействованы неявные параметры.

У меня есть следующая (короткая версия) моего кода и теста:

Реализация (Scala 2.10, Спрей и Акка):

import spray.httpx.SprayJsonSupport._
import com.acme.ResultJsonFormat._

case class PerRequestIndexingActor(ctx: RequestContext) extends Actor with ActorLogging {
  def receive = LoggingReceive {
    case AddToIndexRequestCompleted(result) =>
      ctx.complete(result)
      context.stop(self)
  }
}


object ResultJsonFormat extends DefaultJsonProtocol {
  implicit val resultFormat = jsonFormat2(Result)
}

case class Result(code: Int, message: String)

Тест (использование ScalaTest и Mockito):

"Per Request Indexing Actor" should {
    "send the HTTP Response when AddToIndexRequestCompleted message is received" in {
      val request = mock[RequestContext]
      val result = mock[Result]

      val perRequestIndexingActor = TestActorRef(Props(new PerRequestIndexingActor(request)))
      perRequestIndexingActor ! AddToIndexRequestCompleted(result)

      verify(request).complete(result)
    }
  }

В этой строке verify(request).complete(result) используется неявный Marshaller, чтобы превратить Result в JSON.

Я могу привести маршаллера в область видимости, добавив implicit val marshaller: Marshaller[Result] = mock[Marshaller[Result]], но когда я запускаю тест, используется другой экземпляр Marshaller, поэтому проверка не выполняется.

Даже явно передается макет Marshaller на complete.

Итак, может ли кто-нибудь посоветовать создать макет объекта для неявного параметра и убедиться, что экземпляр используется?

Ответ 1

Это идеальная ситуация для использования Matcher от Mockito для аргументации marshaller. Вам не нужно будет издеваться над неявным маршаллером. Все, что вы действительно хотите сделать, это проверить, что complete был вызван с result, соответствующим тому, что вы ожидали, а также некоторому экземпляру маршаллера. Во-первых, если вы еще этого не сделали, приведите маркеры Mockito в область видимости с таким им образом:

import org.mockito.Matchers._

Затем, если вам нужно сопоставление ссылок на результат, вы можете убедиться в следующем:

verify(request).complete(same(result))(any[classOf[Marshaller[Result]]])

Или, если вы хотите, чтобы результат равный по результату, вы могли бы сделать:

verify(request).complete(eq(result))(any(classOf[Marshaller[Result]]))

Трюк с помощниками заключается в том, что после того, как вы используете один для одного аргумента, вы должны использовать его для всех аргументов, поэтому мы должны использовать его и для result.