我正在使用 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/