Reputation: 330
I have to test trait that contains a private val, but this val need to be override for testing propose.
trait A {
private val someVariable = 0
}
test class
@RunWith(classOf[JUnitRunner]) class ATest extends FunSuite {
val a = new A{
override private val someVariable = 1
}
test("test of someVariable ){
assert(a.someVariable == 1) //I know that I can't print private variable in this way, but it is just for showing what I need.
}
}
Is here some way how to override this variable? Thanks
Upvotes: 1
Views: 2328
Reputation: 39577
The trait initializer also needs to set that field, so you can exploit that public synthetic setter:
scala> :pa -raw
// Entering paste mode (ctrl-D to finish)
package XX { trait X { private val x = 42 ; def test = x * 2 } }
// Exiting paste mode, now interpreting.
scala> (new XX.X {}).test
res0: Int = 84
scala> val v = new XX.X {}
v: XX.X = $anon$1@3cd1f1c8
scala> classOf[XX.X].getDeclaredMethod("XX$X$_setter_$XX$X$$x_$eq", classOf[Int])
res1: java.lang.reflect.Method = public abstract void XX.X.XX$X$_setter_$XX$X$$x_$eq(int)
scala> res1.invoke(v, 3: Integer)
res2: Object = null
scala> v.test
res3: Int = 6
There's more than one way to reflectively skin a cat.
Upvotes: 2
Reputation: 330
I modified my trait to
trait A {
private[package] val someVariable = 0
}
Now it's working.
Upvotes: 0