The latest version of ScalaTest, a testing tool for Scala and Java developers, includes a concise way to test private methods and support for behavior-driven development.
On Christmas Eve I finally made another release of ScalaTest. During the six months since the previous release I had been quite busy with getting the Programming in Scala book out the door. I did keep working on ScalaTest during that time, with most time spent designing a way to do behavior-driven development with ScalaTest. This process involved trying many, many different ways to do Specs and matchers. Trait Spec is a subtrait of Suite, so you run it just like any other ScalaTest suite. The matchers are not included in this release, but should be in the next release. If you want a sneak peak you can see ScalaTest matchers in action in the source code released in the 0.9.4 distribution zip file.
ScalaTest 0.9.4 also includes a PrivateMethodTester trait, which provides a concise way to test private methods. To use it, you first create a PrivateMethod object, like this:
val decorateToStringValue = PrivateMethod[String]('decorateToStringValue)
The val defines a variable, named decorateToStringValue (the name of the private method you'd like to test), which is initialized with a reference to the PrivateMethod object created by the expression on the right of the equals sign. The String in square brackets is a type parameter. (Scala uses square brackets for type parameters instead of the angle brackets used by Java, C#, C++, etc. Thus in any of these other languages you'd see <String> instead of [String].) This type parameter indicates the result type of the private method you want to test. The 'decorateToStringValue is called a symbol in Scala. It is a essentially a special kind of string that starts with a tick mark and ends with the first non-identifier character. Symbols provide a concise way to talk about the symbols of your program, in this case, the name of a private method you want to invoke.
Given this syntax, Scala will invoke a method named apply on the PrivateMethod "singleton object." This is analogous to invoking a static method named apply on class PrivateMethod in Java. So the Scala compiler will rewrite the previous code to this:
val decorateToStringValue = PrivateMethod.apply[String]('decorateToStringValue)
In this case apply is a factory method that instantiates a PrivateMethod instance that is parameterized with the result type and knows the name of the private method you wish to test.
To actually test the private method, you use the invokePrivate operator, like this:
val result = targetObject invokePrivate decorateToStringValue(1)
Here, targetObject is a variable or singleton object name referring to the object whose private method you want to test. You pass the arguments to the private method in the parentheses after the PrivateMethod object.
The result type of an invokePrivate operation will be the type parameter of the PrivateMethod object, thus you need not cast the result to use it. (In this case, the Scala compiler will infer the type of result to be String.) In other words, after creating a PrivateMethod object, the syntax to invoke the private method looks like a regular method invocation, but with the dot (.) replaced by invokePrivate. The private method is invoked dynamically via reflection, so if you have a typo in the method name symbol, specify the wrong result type, or pass invalid parameters, the invokePrivate operation will compile, but throw an exception at runtime.
Version 0.9.4 also has several other minor changes, and a few deprecated features. For the complete details, and to download, go to: