A Bit of Lovin’ for the Groovy Object Initialization

Posted by & filed under , .

iStock_000002882014XSmallI’m going to spread some lovin’ today for the widely-used yet less appreciated feature in Groovy which allows creating a Java bean and setting its properties in one line. Especially when dealing with unit tests this saves me a great deal of time and frustration.

If you ever worked with “pure” (??) Java beans, then you are familiar with classes with a public (quite often default) constructor with no parameters and a whole suite of setters and getters. This is such a common pattern that a lot of the IDE’s nowadays offer automated tasks for creating get/set for given private members so you don’t have to worry about these.

More often than not, the generated Java bean has only a no-params default constructor, which is where my frustrations come in, as when dealing with instances of this class you have to write a few lines of code to actually initialize a piece of data to use in your tests!

Consider this class for instance (encapsulating loosely a person data):

public class Person {
   private String name;
   private String surname;
   private int age;
   public String getName() { return name; }
   public String setName(String name) { this.name = name; }
   public String getSurname() { return surname; }
   public String setSurname(String surname) { this.surname = surname; }
   public int getAge() { return age; }
   public int setAge(int age) { this.age = age; }

Now in my unit test if I want to model myself (yup, I’m still 21 :D) I have to write this sort of code:

Person liv = new Person();
p.setName( "Liviu" );
p.setSurname( "Tudor" );
p.setAge( 21 );

That sucks! 4 lines of code for a darn Java bean?

Of course, if you work with code from more thoughtful programmers, you might also have an all-properties constructor, such as:

public class Person {
   private String name;
   private String surname;
   private int age;
   public Person(String name, String surname, int age) {
      this.name = name;
      this.surname = surname;
      this.age = age;
   // ...

Then you can write a one-liner for the above:

Person liv = new Person( "Liviu", "Tudor", 21);

Especially when you write unit tests I love this approach as I want to concentrate on writing the code not initializing the data. However, as I said, this is not always possible, especially if you are dealing with data from 3rd party libraries.

And this is where Groovy makes it so nice to create and initialize a bean in one line again by using this approach:

def liv = new Person( name: "Liviu", surname: "Tudor", age: 21 )

Done! This simply compiles to

def liv = new Person()
liv.name = "Liviu"
liv.surname = "Tudor"
liv.age = 21

So it’s under the cover the same thing… but I get to do this in one line and not pollute my code with initialization code. Groovy, baby!