How can a private class method be tested in Scala?

@jlegler's answer here helped me, but I still had some debugging to do before things worked, so I thought I'd write exactly what's needed for this here.

to test:

class A

object A {
  private def foo(c: C): B = {...}
}

use:

val theFuncion = PrivateMethod[B]('foo)
val result = A invokePrivate theFunction(c)

Note the locations of A, B


You could declare your method to be package private:

private[people] def transform(p: Person): Person = new Person(p.age + 1)

If you put PersonSpec in the same package it will be able to access it.

I leave it to you to decide if it's really wise to unit test a private method :)


I am in the middle when it comes to testing everything. I don't usually test everything, but sometimes it's really useful to be able to unit test a private function without having to mangle my code to make it possible. If you're using ScalaTest, you can use the PrivateMethodTester to do it.

import org.scalatest.{ FlatSpec, PrivateMethodTester }

class PersonSpec extends FlatSpec with PrivateMethodTester {

  "A Person" should "transform correctly" in {
      val p1 = new Person(1)
      val transform = PrivateMethod[Person]('transform)
      // We need to prepend the object before invokePrivate to ensure
      // the compiler can find the method with reflection
      assert(p2 === p1 invokePrivate transform(p1))
    }
  }

That may not be exactly what you want to do, but you get the idea.


The need to unit-test private methods is a design smell.

Either you test them through your public API which is ok if they are small and just helper methods - or, which is more likely, it contains different logic/responsibility and should be moved to another class that is used by delegation in the Person. Then you would test the public API of that class first.

See a related answer for more details.

Likely you can access it using Java/Scala reflection, but it is just a workaround for the design problem. Still, if you need to, see a related Java answer how to do that.