scala - 无法在 Scala 中使用 Mockito ArgumentMatchers

标签 scala mockito

我正在使用 ScalaMock 和 Mockito

我有这个简单的代码

class MyLibrary {
   def doFoo(id: Long, request: Request) = {
      println("came inside real implementation")
      Response(id, request.name)
   }
}

case class Request(name: String)
case class Response(id: Long, name: String)

我可以使用这段代码轻松模拟它

val lib = new MyLibrary()
val mock = spy(lib)
when(mock.doFoo(1, Request("bar"))).thenReturn(Response(10, "mock"))
val response = mock.doFoo(1, Request("bar"))
response.name should equal("mock")

但是如果我将我的代码更改为

val lib = new MyLibrary()
val mock = spy(lib)
when(mock.doFoo(anyLong(), any[Request])).thenReturn(Response(10, "mock"))
val response = mock.doFoo(1, Request("bar"))
response.name should equal("mock")

我看到它进入了真正的实现并得到了一个空指针异常。

最佳答案

我很确定它也进入了没有匹配器的真实实现中,不同之处在于它在那种情况下不会崩溃(any 最终将 null 传递给调用)。

当您编写 when(mock.doFoo(...)) 时,编译器必须调用 mock.doFoo 来计算传递给 什么时候

mock 做这个是可行的,因为所有的实现都被删除了,但是 spy 包裹了实际的对象,所以,实现也是真实的。

spy 在 mockito 世界中是不受欢迎的,被认为是代码味道。 如果您发现自己不得不模拟类的一些功能,同时保留其余部分,那么几乎可以肯定的是,您应该将它分成两个单独的类。然后您就可以完全模拟整个“底层”对象,而无需监视事物。

如果您出于某种原因仍然设置使用 spy ,doReturn 将是解决方法,正如其他答案所建议的那样。你不应该将 null 作为 vararg 参数传递,它会改变调用的语义。这样的事情应该有效:

 doReturn(Response(10, "mock"), Array.empty:_*).when(mock).doFoo(any(), any())

但是,我要再次强调:这只是一种解决方法。正确的解决方案是使用 mock 而不是 spy 开始。

关于scala - 无法在 Scala 中使用 Mockito ArgumentMatchers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45165926/

相关文章:

java - 莫基托。模拟抛出异常的单个方法

android - 类路径资源被(可能)sbt 复制

scala - 在 Play Framework 中部署修复的最佳实践

amazon-web-services - 如何用 Mockito 模拟 DynamoDB?

java - REST 模板的 Mockito 单元测试

android - 将 Mockito Matchers.any() 与 android.support.annotation.IntDef 自定义注释一起使用

java - 检查对象数组上的模拟调用

json - 使用 lift-json 是否有一种简单的方法来提取和遍历列表?

json - 在Scala的剧本中使用Json序列化处理具有多个案例类(和类型)的特质

scala - 使用 Scala 中的 QueryParamDecoder 解码可选查询参数