Вызов doAnswer с функцией в качестве аргумента в scala play 2.4

Я хочу смоделировать метод с обратным вызовом в аргументе, скажем:

methodToMock[T](callback: (String, String) => T)

С игрой 2.3, (specs2 версия 2.3.8) мне удалось сделать это методом doAnswer от мокито:

doAnswer({ invocation =>
  val method = invocation.asInstanceOf[(String, String) => Any] // L.34
  method(role, key)
}).when(myMock).methodToMock[Any](any)

Но, начиная с игры 2.4 (используя специальные спецификации зависимостей 2, версия 2.4.2), предыдущий код не будет работать, сказав мне:

[Ljava.lang.Object; cannot be cast to scala.Function2 (MySpec.scala:34)

Я не очень понимаю, почему mockito начал использовать объекты Java в моем коде, так как я использую реализацию specs2 и не нашел никакой документации по изменениям в doAnswer, ни пример использования моего варианта использования.

Ты хоть представляешь, что я сделал не так и как это решить?

РЕДАКТИРОВАТЬ:

Я хотел показать упрощенный случай, но это удалило источник проблемы... Настоящее определение метода также принимает список неявных аргументов:

methodToMock[T](callback: (String, String) => T)(implicit value: String)

Это означает, что specs2, кажется, возвращает массив вместо одного элемента (его поведение действительно изменилось между двумя версиями).

Следующий код теперь работает

doAnswer({ invocation =>
  val firstArgList = invocation.asInstanceOf[Array[Object]](0)
  val method = firstArgList.asInstanceOf[(String, String) => Any] // L.34
  method(role, key)
}).when(myMock).methodToMock[Any](any)(any)

1 ответ

Решение

Какую версию specs2 вы используете? С 3.6.5 (самое последнее) следующее прекрасно работает

case class T() {
  def methodToMock[A](callback: (String, String) => A) = 1
}

val m = mock[T]

doAnswer({ invocation =>
  val method = invocation.asInstanceOf[(String, String) => Any] // L.34
  method("role", "key")
}).when(m).methodToMock[Any](any)

m.methodToMock((s: Any, s2: Any) => s.toString.size + s2.toString.size) === 7
Другие вопросы по тегам