franki3xe
franki3xe

Reputation: 330

Is possible to override private val in scala trait

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

Answers (2)

som-snytt
som-snytt

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

franki3xe
franki3xe

Reputation: 330

I modified my trait to

trait A {
  private[package] val someVariable = 0
}

Now it's working.

Upvotes: 0

Related Questions