1.23.2011

Testing Toolbelt: Groovy

Groovy, the apparent golden child of Java, is a mostly dynamic-typed JVM language which seeks to add functionality to the core Java language such that writing and testing code is much easier and requires less boiler-plate code. Some of the features provided by Groovy that I have found useful for testing are:

GroovyBean Properties and Constructors

Groovy attempts to simplify the usage of bean-type object by providing some shortcuts for accesses and assignments. By default, every class accessed through Groovy code is decorated with a default constructor which takes a map (property->value), and a getter and setter for each field defined in the class (for which there is not already a getter/setter). The constructor is a simple way to provide values to properties of the new instance.

properties-sample.groovy

Token Replacement

In Groovy, the String class is enhanced to allow for the use of tokens within a String literal. These tokens are of the form ${<property>} and will use the properties values available at the time of creation. Refer back to the above example to see some at work.

Collection Literals

Easily create a list by using the [] syntax, a range by using the <start>..<end> syntax, and a map by using the [<key>:<value>] syntax.

collection-sample.groovy

Closures

Closures are simply blocks of code surrounded by curly braces, which can be treated as reference types. Closures may declare arguments and may return values. Closures may be stored in variables.

closure-sample.groovy

Iteration (each)

Iteration of arrays, ranges, lists, and maps has been simplified by the addition of the each method.

each-sample.groovy

Coercion (Map and Closure)

Any map or closure may be interpreted as an instance of a specific type simply by using as <type>. This allows you to easily create stand-in objects, provided they have a public default (no-arg) constructor.

coercion-sample.groovy

GDK

Through the default meta-class implementations used by Groovy, many useful methods (many taking advantage of closures) have been added to the standard Java classes. There's too much to list here, but know that many of the above examples use GDK methods.

GroovyTestCase

The GroovyTestCase class contains a large portion of the testing functionality used by basic Groovy. Since the Groovy team have pledged backwards-compatibility with JDK 1.4, they have also stuck with the non-annotation-based version of JUnit(3.8.*) as a basis for their testing helper class. This is not as bad as it sounds, as many of the language features of Groovy make up for the missing capabilities of JUnit 4.4. Every test class defined using groovy must be a sub-class of GroovyTestCase. Each test method must be public, return void, and be named test<something>.

assert*

all of the assert* methods provided by JUnit are also present in the GroovyTestCase class.

shouldFail(<Throwable>)

similar to the Test annotation when used with the expected argument, the shouldFail method takes a Throwable class type and a closure, executes the closure, and fails if an instance of Throwable is not thrown within the closure.

shouldFail-sample.groovy

StubFor and MockFor

The StubFor/MockFor classes can be used within Groovy to create stand-in objects when coercion won't work or when you need to over-ride the behavior of a constructor.

stubfor-sample.groovy

No comments: