0

I am using ScalaMock3 and I am trying to create a mock of a javax.jms.TextMessage within my ScalaTest spec.

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"
    }
  }
}

However, when I try to compile, I get the following:

[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] 
                      ^

Looking online, I found this (unresolved) issue, but I was hoping someone could suggest a work-around at least...

Thanks

mdm
  • 3,928
  • 3
  • 27
  • 43

4 Answers4

1

Basically this happens because of the API differences between Java 1.4 and >= 1.5 versions.

TextMessage uses the Java 1.4 non-generic type java.util.Enumeration (return type from getPropertyNames inherited from javax.jms.Message), whereas in newer JVMs java.util.Enumeration<E> is a generic class with a type parameter.

When ScalaMock tries to create a mocked instance of this interface, it fails there:

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

I don't think there's much you can do unfortunately.

cbley
  • 4,538
  • 1
  • 17
  • 32
1

There is a fixed issue for ScalaMock: https://github.com/paulbutcher/ScalaMock/issues/29

Add this to your code:

implicit val d = new Defaultable[java.util.Enumeration[_]] {
  override val default = null
}
vnfedotov
  • 21
  • 4
0

While it's not an optimal solution, embedding the offending class in a wrapper class allows for mocking the behavior within your test suite.

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

  def getMessage() = textMessage.getMessage()
}

You can then pass wrapper.textMessage wherever an instance of TextMessage is required

Shane Perry
  • 980
  • 7
  • 12
0

Have you tried this?

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")
    }

I did something similar when I got this error with java.util.List<T> and the compiler stopped complaining after this.

gred
  • 612
  • 1
  • 8
  • 15