使用 mockito 模拟函数内部的 scala 对象调用
using mockito to mock a scala object call inside a function
我正在尝试测试以下功能
class someClass {
def someMethod() = {
val x = someObject.someOtherMethod()
//some logic that i want to test
}
}
有没有办法在不传递 x 的情况下模拟 val x 或 someOtherMethod 调用
如果 SomeObject 确实是一个 Object
,我不相信存在,缺少一些反射黑魔法。
一个常见的模式是拥有一个特征来定义对象的 public 方法,并让对象扩展该特征。
现在 SomeClass
可以依赖 SomeObject
特征:例如
trait SomeObject {
def someMethod: Unit
}
object SomeObject extends SomeObject {
def someMethod = println("real method called")
}
class SomeClass(someObject: SomeObject)
并且在测试中你可以模拟特征:
val mockObject = mock[SomeObject]
when(mockObject.someMethod).thenReturn(())
val someClass = new SomeClass(mock[SomeObject])
编辑:一些 Unsafe
魔法。
import sun.misc.Unsafe
object Foo {
val length: String => Int = {s => s.length}
}
Foo.length("foo") // 3
val unsafe = {
val f = classOf[Unsafe].getDeclaredField("theUnsafe")
f.setAccessible(true)
f.get(null).asInstanceOf[Unsafe]
}
val offset = unsafe.objectFieldOffset(Foo.getClass.getDeclaredField("length"))
val doubleLength: String => Int = { s=> s.length * 2}
unsafe.putObject(Foo, offset, doubleLength)
Foo.foo("foo") // 6
不幸的是,当 Foo.length
是 def
而不是 val
时,我无法完成这项工作
我正在尝试测试以下功能
class someClass {
def someMethod() = {
val x = someObject.someOtherMethod()
//some logic that i want to test
}
}
有没有办法在不传递 x 的情况下模拟 val x 或 someOtherMethod 调用
如果 SomeObject 确实是一个 Object
,我不相信存在,缺少一些反射黑魔法。
一个常见的模式是拥有一个特征来定义对象的 public 方法,并让对象扩展该特征。
现在 SomeClass
可以依赖 SomeObject
特征:例如
trait SomeObject {
def someMethod: Unit
}
object SomeObject extends SomeObject {
def someMethod = println("real method called")
}
class SomeClass(someObject: SomeObject)
并且在测试中你可以模拟特征:
val mockObject = mock[SomeObject]
when(mockObject.someMethod).thenReturn(())
val someClass = new SomeClass(mock[SomeObject])
编辑:一些 Unsafe
魔法。
import sun.misc.Unsafe
object Foo {
val length: String => Int = {s => s.length}
}
Foo.length("foo") // 3
val unsafe = {
val f = classOf[Unsafe].getDeclaredField("theUnsafe")
f.setAccessible(true)
f.get(null).asInstanceOf[Unsafe]
}
val offset = unsafe.objectFieldOffset(Foo.getClass.getDeclaredField("length"))
val doubleLength: String => Int = { s=> s.length * 2}
unsafe.putObject(Foo, offset, doubleLength)
Foo.foo("foo") // 6
不幸的是,当 Foo.length
是 def
而不是 val