ScalaMock не будет издеваться над моим TextMessage

Я использую ScalaMock3, и я пытаюсь создать макет javax.jms.TextMessage в моей спецификации ScalaTest.

import javax.jms.TextMessage
import org.scalamock.scalatest.MockFactory
import org.scalatest.{Matchers, WordSpecLike}

class MySpec extends WordSpecLike
  with Matchers
  with MockFactory {

  "MySpec" should {
    "create the mock I want!" in {

      val msg = mock[TextMessage]
      msg.getText _ expects() returning "my_text"

      msg.getText shouldBe "my_text"
    }
  }
}

Однако, когда я пытаюсь скомпилировать, я получаю следующее:

[error] /my/path/MySpec.scala:14: could not find implicit value for evidence parameter of type org.scalamock.util.Defaultable[java.util.Enumeration]  
[error] val msg = mock[TextMessage] 
                      ^

Посмотрев в Интернете, я нашел эту (нерешенную) проблему, но я надеялся, что кто-нибудь может предложить обходной путь хотя бы...

Спасибо

3 ответа

Для ScalaMock существует исправленная проблема: https://github.com/paulbutcher/ScalaMock/issues/29

Добавьте это к своему коду:

implicit val d = new Defaultable[java.util.Enumeration[_]] {
  override val default = null
}

В основном это происходит из-за различий API между версиями Java 1.4 и>= 1.5.

TextMessage использует неуниверсальный тип Java 1.4 java.util.Enumeration (тип возврата от getPropertyNames унаследованный от javax.jms.Message), тогда как в более новых JVM java.util.Enumeration<E> является универсальным классом с параметром типа.

Когда ScalaMock пытается создать поддельный экземпляр этого интерфейса, он терпит неудачу там:

null.asInstanceOf[java.util.Enumeration] 
Main.scala:46: trait Enumeration takes type parameters

Я не думаю, что вы многое можете сделать, к сожалению.

Хотя это не оптимальное решение, встраивание нарушающего класса в класс-оболочку позволяет имитировать поведение в вашем наборе тестов.

class TextMessageWrapper {
  lazy val textMessage: TextMessage = ???

  def getMessage() = textMessage.getMessage()
}

Затем вы можете пройти wrapper.textMessage везде, где экземпляр TextMessage необходимо

Вы пробовали это?

implicit object DefaultableEnumeration extends Defaultable[java.util.Enumeration[Object]] {
    val default = new java.util.Enumeration[Object] {
        override def hasMoreElements: Boolean = false
        override def nextElement: Object = throw new NoSuchElementException("no elements")
    }

Я сделал нечто подобное, когда я получил эту ошибку с java.util.List<T> и компилятор перестал жаловаться после этого.

Другие вопросы по тегам