I'm trying to test the following function
class someClass {
def someMethod() = {
val x = someObject.someOtherMethod()
//some logic that i want to test
}
}
Is there a way to mock val x or the someOtherMethod call without passing x
If SomeObject is truly an Object
, I don't believe there is, short of some reflection black magic.
A common pattern is to have a trait that defines the public methods of the object, and have the object extend the trait.
Now SomeClass
can depend on the SomeObject
trait: e.g.
trait SomeObject {
def someMethod: Unit
}
object SomeObject extends SomeObject {
def someMethod = println("real method called")
}
class SomeClass(someObject: SomeObject)
and In tests you can mock the trait:
val mockObject = mock[SomeObject]
when(mockObject.someMethod).thenReturn(())
val someClass = new SomeClass(mock[SomeObject])
edit: Some Unsafe
magic.
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
Unfortunately I couldn't make this work when Foo.length
is a def
and not a val