Scala Value类和Mockito Matchers不能一起玩

lon*_*uro 9 scala mockito

在Mockito Mocks(Matchers)中使用Scala的值类会导致NullPointerException,请参阅以下示例:

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)
  }
}
Run Code Online (Sandbox Code Playgroud)

结果是:

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)
Run Code Online (Sandbox Code Playgroud)

有什么提示可以在这做什么?

joh*_*ren 4

假设 NPE 发生在 Mockito.when-line 上,我猜这是因为值类被实现为实际传递原语,然后用静态方法替换其上的方法调用,而 Mockito 想要在对象上调用 equals,或类似的东西。如果这是原因,那么也许您可以在 Scala 中实现自己的匹配器来解决它。

  • 正如我现在发现的,它发生在“Matchers.eq(id)”上,因为mockito试图确定Id值类的默认值,该值是空的,因为在运行时它扩展了java.lang.Object,并且对象的默认值是无效的。另一方面,编译器希望将“原始 int”“装箱”到 scala.Int 中 (3认同)