10

Using Scala's value classes with Mockito Mocks (Matchers) results in a NullPointerException, see this example:

import org.scalatest.FunSuite
import org.scalatest.mock.MockitoSugar._
import org.mockito.{Matchers, Mockito}

class Id(val underlying: Int) extends AnyVal

class MockitoValueClassSuite extends FunSuite {

  trait Sample {
    def doIt(id: Id) : Int
  }

  test("Check value classes in scala with mockito") {
    val sampleMock = mock[Sample]

    val id = new Id(1)

    Mockito.when(sampleMock.doIt(Matchers.eq(id))).thenReturn(5)

    assert(sampleMock.doIt(id) == 5)
  }
}

Results in:

java.lang.NullPointerException was thrown.
java.lang.NullPointerException
    at net.gutefrage.service.user.service.MockitoValueClassSuite$$anonfun$1.apply$mcV$sp(MockitoValueClassSuite.scala:21)
    at net.gutefrage.service.user.service.MockitoValueClassSuite$$anonfun$1.apply(MockitoValueClassSuite.scala:16)
    at net.gutefrage.service.user.service.MockitoValueClassSuite$$anonfun$1.apply(MockitoValueClassSuite.scala:16)
    at org.scalatest.Transformer$$anonfun$apply$1.apply(Transformer.scala:22)

Any hints what can be done here?

Chris W.
  • 2,266
  • 20
  • 40

2 Answers2

4

Assuming that the NPE happens on the Mockito.when-line I'd guess it is because the value classes are implemented as actually passing around the primitive and then replacing method calls on it with static methods while Mockito wants to call equals on an object, or something like that. If that is the reason then maybe you could implement your own matcher in Scala to work around it.

johanandren
  • 11,249
  • 1
  • 25
  • 30
  • 3
    As I found out now, it happens on "Matchers.eq(id)", as mockito tries to determine a default value for the Id value class which is null because at runtime it extends java.lang.Object and the default for Objects is null. The compiler on the other hand wants to have a "primitive int" to "box" into a scala.Int – Chris W. Nov 14 '13 at 13:45
1

In your case, you have to use something like this:

Mockito.when(sampleMock.doIt(Id(Matchers.eq(id)))).thenReturn(5)

or

Mockito.doReturn(5).when(sampleMock).doIt(Id(Matchers.eq(id)))
mr MR
  • 131
  • 2
  • 2