Groovy knowledge for Spock testing - GETTING STARTED - Java Testing with Spock, Version 6 (2015)

Java Testing with Spock, Version 6 (2015)

PART 1: GETTING STARTED

Chapter 2. Groovy knowledge for Spock testing

In this chapter

· Understanding the connection between Java and Groovy

· Learning the Groovy conventions

· Comparing JUnit asserts and Groovy power assert

· Groovy utilities for common testing needs

· Obtaining test data with Groovy

Learning a new programming language is usually a daunting task. You must study a new syntax, new concepts, and new libraries all at once to be productive. If you’ve spent too many years with a single language, several concepts are so entrenched that having to "unlearn" them poses a big barrier to any alternative (even if it is objectively better). With Groovy this is not the case, because Groovy is a cousin language to Java. Much of your current knowledge can be reused and extended instead of thrown away.

In this chapter I will give you a crash course into Groovy essentials. It’s important to know your way around Groovy code before writing Spock tests. I have seen several Java developers who jump into Spock, and just write the same JUnit-like tests as they did before.

Because the subject of this book is the Spock testing framework (and in extension other relevant testing topics), all Groovy capabilities listed are those relevant to unit tests only. Groovy has many more features aimed at writing production code (and not unit test code). Explaining all concepts of Groovy is impossible in a single chapter, and there is no reason to do so because there are already extensive books on vanilla Groovy that you should consult if you decide to use it outside of Spock unit tests.

Apart from the "Groovy in Action" book which is the major source for all things Groovy, I can also recommend "Making Java Groovy" which is emphasizing the augmenting role of Groovy compared to Java (both books are published by Manning).

2.1 What you need to know about Groovy

If you already know "Java", you actually have knowledge in three distinct areas:

1. The syntax/keywords of the Java language

2. The Java Development Kit (JDK) that contains many helpful collections and utilities

3. The Java Runtime (Java Virtual Machine)

It would be a mistake to think that learning Groovy is like learning a new programming language from scratch. Groovy was designed as a companion to Java.

Groovy offers the productivity boost of a dynamic language (think Python or Ruby) because it doesn't have so many restrictions as Java. But at the same time it runs in the familiar JVM and can take advantage of all Java libraries. It completely removes some bulky features of Java and always attempt to minimize boilerplate code with just the gist of what you are doing.

Java is very mature as a platform, but as a language it sometimes lags behind in some areas (e.g. concurrent facilities or until recently functional constructs) that usually are filled by external frameworks. Groovy closes this gap and provides you with a modern language aimed at productive code sessions in a stable and mature ecosystem of libraries.

Groovy syntax is a superset of Java syntax. Almost all Java code (with some exceptions) is valid Groovy code as well. The Groovy Development Kit (GDK) is an enhanced version of the JDK. And most importantly of all Groovy runs on the JVM exactly like Java!

For those reasons your journey into the magic world of Groovy should be a pleasant adventure in a different but familiar land. If Java is not the only language you speak but you have some experience with other dynamic languages such as Python or Ruby, picking up the basics of Groovy would be an even easier matter.

In a nutshell Groovy:

1. is a dynamic language (Java is static)

2. is a strongly typed language (same as Java)

3. is object oriented (same as Java)

4. comes with GDK (Java has JDK)

5. runs on the JVM (same as Java)

6. favors concise code (Java is considered verbose)

7. offers its own libraries (e.g. web and object relational frameworks)

8. can use any existing Java library as is (Java can also call Groovy code)

9. has closures (Java 8 has lambda expressions)

10.supports duck typing[7] (Java has strict inheritance)

We will explore the most important concepts in the next sections and show side-by-side Java and Groovy code where appropriate. I spent a lot of time thinking which of all Groovy features I would showcase in this chapter. I decided to split Groovy features into four categories: essential, useful, advanced, everything else.

· Sections 2.1 and 2.2 contain knowledge that I consider essential for Spock tests.

· Sections 2.3, and 2.4 contain Groovy features that you will find useful in your everyday contact with Spock but are not otherwise essential.

· Section 2.5 contains some advanced Groovy features that you may need in your Spock tests in about 20%[8] of cases.

· Finally, the rest of Groovy features were left out of this book. (even if some of them are essential for writing production code and not unit tests). I invite you to look at the official Groovy web page for more details on things that I have not included here (and they are a lot).

What is the biggest difficulty while learning Groovy as a Java programmer?

The biggest barrier (in my opinion) to learning Groovy, if Java is the only language you know, is the dynamic nature of Groovy. In Java there is a direct mapping between a source file and a class. If you know the source code you know everything there is to know about a class.

In Groovy a class/object can change during runtime in ways that are impossible with Java. For example it is possible to add new methods on a Groovy object (that were not in its source code), delegate existing methods to other objects or even create completely new classes during run time out of thin air. If you thought that Java introspection was a fancy trick, Groovy has a complete repertoire of magic tricks that will leave your head spinning on all the possibilities.

Fortunately all these Groovy features are not essential for unit tests so you do not need to be overwhelmed with too much information while you are learning Spock. If you decide to use Groovy in production code and not just Spock tests, some of its capabilities will certainly amaze you if you have never worked with a dynamic language before.

2.1.1 Groovy as a companion to Java

Your first contact with Groovy is probably with the new syntax. Sometimes when I look at Groovy code I think the syntax is a subset of Java because Groovy does away with many redundant Java features. Other times I think that Groovy syntax is a superset of Java because it adds capabilities into existing well known Java structures. The fact is that the Groovy code is more expressive. I promised in the previous chapter that writing your unit tests in Groovy would result in less code than Java. Now it is the time to look at this promise.

How to use the code listings

You can find almost all code listings of this book in https://github.com/kkapelon/java-testing-with-spock . For brevity reasons the book sometimes will point you to the source code (especially for long listings).

I use the Eclipse IDE in my day to day work as shown in the screenshots throughout the book. You can find specific instructions for installing Spock (including the optional Groovy installation) and the Eclipse IDE (plus some information on alternative IDE’s) in Appendix A.

Let's start with the Groovy basics: automatic creation of getters and setters as well as default visibility modifiers in, as shown in this next listing.

Listing 2.1 Groovy class conventions

class Person { #A String firstName #B String lastName int age} class GettersSettersDemo { #C public static void main(String[] args) #D { Person person = new Person() #E person.setFirstName("Lyta") #F person.setLastName("Alexander") System.out.println("Person first name is "+person.getFirstName()) #G System.out.println("Person last name is "+person.getLastName()) }}

#A Contents of file Person.groovy

#B Fields are private, no semicolons

#C Contents of file GettersSettersDemo.groovy

#D main method writen in Java like manner

#E creating a class just like Java

#F Using the automatically generated setter

#G Using the automatically generated getter

As can be seen in listing 2.1:

1. classes are public by default

2. fields are private by default

3. getters and setters are automatically created during runtime and thus do not need to be included in the class declarations.

4. semicolons are optional and should be used in case of multiple statement in the same line.

These are some of the basic conventions that allow Groovy to cut back on the amount of boilerplate. The biggest gain comes from the removal of getters and setters. You are free to define a setter/getter if you need to implement it in a different way other than the default. Even though our Person.groovy class is written in idiomatic Groovy, the GettersSettersDemo is still very Java like.

We can cut down even further the amount of code using the Groovy way of field accessing as shown in listing 2.2

List 2.2 Groovy field conventions

class GettersSettersDemo2 { public static void main(String[] args) { Person person = new Person() person.firstName = "Marcus" #A person.lastName = "Cole" println("Person first name is "+person.firstName) #B println("Person last name is "+person.lastName) #C }}

#A This still calls person.setFirstName() behind the scenes

#B This still calls person.getFirstName() behind the scenes

#C All Groovy objects inherit println method that outputs messages to console

As seen in listing 2.2 Groovy not only supports the autogeneration of getters and setters, but also allows using just the name of the field instead of the method. The getter or the setter is implicitly called according the surrounding context. Finally as a shortcut to System.out.println Groovy makes available the println method to any object.

We are not finished yet. We can further refine the code by removing completely the main method and employing Groovy Strings to reach finally the state of idiomatic Groovy as shown in listing 2.3

Listing 2.3 A complete Groovy script

class Person { #A String firstName String lastName int age String rank} Person person = new Person() #Bperson.firstName = "Susan "person.lastName = "Ivanova"person.rank = "Commander " println "Person first name is $person.firstName" #Cprintln "Person last name is $person.lastName" #Dprintln "Person rank is $person.rank"

#A The Person class is defined in the file GettersSettersDemo3.groovy

#B All code outside of the class is the "main" method

#C The $ character performs string interpolation like JSP/JSTL does

#D Parentheses are optional for non-void methods

In Groovy the class name is not required to match the name of the source file. Also the main method is optional. All code that is in the top level of the file is treated as a Groovy script. We can discard completely the helper class and use a single Groovy file that holds both the declaration of the class and its usage. The last piece of the puzzle is the way println is structured. Here I use the interpolation capability of Groovy. The property after the $ is evaluated and inserted directly into the String (which is a Groovy String as you will see later in this chapter). Note that this capability is possible on all strings, not only for those that are printed to the console. Also Groovy makes parentheses optional when calling a method with at least one argument.

At this point you should already see the benefits of Groovy as far as the amount of code is concerned! Here is a complete Spock test that showcases all Groovy featured explained so far. It is a trivial test that will verify a custom string representation of the Person class.

Listing 2.4 A Spock test using concise Groovy code

class PersonSpec extends spock.lang.Specification{ def "Testing getters and setters"() { when: "a person has both first name and last name" SimplePerson person = new SimplePerson() person.firstName = "Susan" #A person.lastName = "Ivanova" then: "its title should be surname, name" person.createTitle() == "Ivanova, Susan" #B } } class SimplePerson { #C String firstName String lastName String createTitle() #D { return "$lastName, $firstName" #E }}

#A Assigning values to fields

#B Spock assertion

#C class defined in the same file as Spock test

#D method that will be tested

#E String interpolation

Here we defined a single Groovy class that contains the Spock test and the class under test for demonstration purposes. The method that is tested uses String interpolation where the fields are replaced with their value inside the resulting text.

In this Spock test both the class under test and the unit test itself are written in Groovy. In the next section you will see how Spock tests that are written in Groovy can actually test Java code.

2.1.2 Accessing Java classes in a Groovy script.

In the previous section you got a small taste of how easy it is to write Groovy code compared to the Java verbose approach. The comparison focused on the syntax of the language. In this section we will compare the way these languages interact during runtime.

Groovy comes with its own compiler (called groovyc) that reads source Groovy files and creates Java bytecode. That is all you need to know in order to understand how Groovy works with Java. As figure 2.1 shows, Groovy source code is converted to the same bytecode already used by Java files.

Figure 2.1 Both Java and Groovy compile in Java bytecode

Then the bytecode is loaded in the JVM exactly like any other Java class. The JVM does not really care about the original source of a class. It runs each Java or Groovy class in the same way offering them both the same capabilities and services.

This is a very important point to remember. Even though as a developer you may feel that Groovy is much more flexible than Java or that Groovy does too many things behind the scenes, it all boils down to the same bytecode of the same JVM. There is not a "Groovy virtual machine." In fact, the Groovy runtime is a single Java archive (JAR) file. Adding Groovy capabilities into an existing Java project is as simple as adding the Groovy JAR into the classpath. Normally your build system takes care of this inclusion making the process of running both Groovy and Java code in the same project an effortless task.

After all is said and done creating and accessing Java objects in Groovy code is exactly the same as in Java code[9]. Listing 2.5 shows a Spock Test (in Groovy) where the class under test is written with Java.

Listing 2.5 Creating and using a Java class from Groovy

public class MilitaryPerson { #A private String firstName; private String lastName; private String rank; public String createTitle() #B { return lastName+", "+firstName +" ("+rank+")"; } public String getFirstName() { return firstName; } ...more getters and setters here..} class MilitaryPersonSpec extends spock.lang.Specification{ #C def "Testing getters and setters of a Java class"() { when: "a person has both first, last name and rank" MilitaryPerson person = new MilitaryPerson() #D person.firstName = "Susan" #E person.lastName = "Ivanova" person.setRank("Commander"); #F then: "its title should be surname, name (rank)" person.createTitle() == "Ivanova, Susan (Commander)" #G } }

#A Class under test is Java code

#B Java method that will be tested

#C Spock test in Groovy

#D Creating a Java class in Groovy code

#E Accessing Java fields using Groovy conventions

#F Java way for accessing fields is also still available

#G Calling a Java method in Groovy code

That is the beauty of Java and Groovy integration. Everything works as expected:

· Groovy code can create Java classes with the new keyword

· Groovy code can call Java methods

· Groovy classes can extend Java classes

· Groovy classes can implement Java interfaces

It doesn't get any easier than this!

2.1.3 Declaring variables and methods in Groovy

One of the first questions every Java developer asks when seeing a Spock test is the usage of the def keyword. The def keyword is one of the central concepts of Groovy that characterize it as dynamically typed [10]. You can find all the details in the Groovy specification if you feel adventurous, but for the purpose of writing Spock tests the meaning of def is "I won't declare a type here, please do it automatically for me."

Thus in Groovy the following is possible:

Listing 2.6 - Groovy optional typing in variables

String firstName = "Susan" #Adef lastName = "Ivanova" #Bdef fullName = "$firstName $lastName" #Cprintln fullName

#A Java way of declaring

#B Groovy optional typing

#C fullName is also a string

As can be seen by Listing 2.6 Groovy supports the usual Java way of declaring things. It also adds its own where the type of the object is inferred by the context. An alternative way to run Groovy files is using the command line and the groovy executable. Listing 2.6 will output:

> groovy DefDemo.groovySusan Ivanova

Is def like Object?

When you are learning Groovy, it’s easy to think that def is an alias for Object. Even though it might seem to work that way, it is something completely different and you can find some big differences with Java if you use it in the wrong way in production code. A suggestion that many Groovy developers embrace is to always declare the type a variable if you know how it will be used. The same suggestion is true for Spock tests too.

It is interesting to note that the def keyword can also be applied in methods as shown in listing 2.7. This can trim the size of Spock test methods even further (after omitting the visibility modifier).

Listing 2.7 Groovy optional typing in methods

def createName(String firstName,String lastName) #A{ return "$lastName, $firstName"} def createMilitaryName(def firstName,def lastName, def rank) #B{ return "$lastName, $firstName ($rank)"} def fullName = createName "Susan","Ivanova" #Cprintln fullName def militaryName = createMilitaryName "Susan","Ivanova","Commander" #Cprintln militaryName

#A Using def for return type

#B Using def for arguments as well

#C Parentheses are optional if at least one argument is used

This listing will output:

> groovy DefDemo2.groovyIvanova, SusanIvanova, Susan (Commander)

Remember that Groovy also supports the Java syntax as well, so it is easy to mix both styles of typing as illustrated. You can gradually convert to Groovy syntax when you feel comfortable with this notation. Now that you know how the def keyword works we can see how it applies to Spock tests:

Listing 2.8 Using dynamic typing in Spock methods

class DefDemoSpec extends spock.lang.Specification{ public void trivialSum1() { #A when: "number is one" int number =1; #B then: "number plus number is two" number + number ==2; } def trivialSum2() { #C when: "number is one" int number = 1 #D then: "number plus number is two" number + number ==2 } def "Testing a trivial sum"() { #E when: "number is one" def number =1 #F then: "number plus number is two" number + number ==2 }}

#A Java way of declaring methods

#B Still using semicolons

#C Groovy way of method declaration

#D Semicolons optional

#E Full string for method name

#F Optional typing of Groovy

As shown in Listing 2.8 the def keyword is part of standard Groovy. It is also possible to use full strings for method names. The final result is the Spock DSL for unit tests. I have written the same unit test in three possible ways. Even though the syntax is different, they run in exactly the same way as far as Spock is concerned.

2.1.4 Writing less code with Groovy

Groovy has still many tricks under its belt for reducing Java code. For example the return keyword is also optional. The last evaluated statement in a method is the result of the method in that case.

In a similar manner the def keyword in arguments is also optional. The example from listing 2.7 can be further simplified using these two rules. Groovy syntax is indeed a refreshing experience when you come from the Java world. Several things that Java considers essential are simply discarded by Groovy, freeing the programmer from boilerplate code that can be automatically created or understood by the runtime.

While learning Spock you will find several ways to cut down on the amount of code, but this does not need to happen right away. My proposal is to follow a gradual learning curve as shown in figure 2.2 below.

Figure 2.2 Suggested path for better Spock tests.

You already know Java. Your first Spock tests should focus on understanding Spock concepts and it is fine if you still write "Java-like" Groovy. Once you understand how Spock works you can apply the shortcuts Groovy offers as illustrated in the previous sections to reduce the amount of code and simplify your Spock tests. When you are confident with Spock you can apply core Groovy techniques (e.g. closures) to write idiomatic Groovy and get completely out of the Java mindset.

A common mistake of Java programmers is writing Spock tests using example code without understanding what feature is Spock specific and what is offered by Groovy. This can make your Spock journey harder that it should be, so don't fall into that trap. Make sure that you know how Spock works before applying cool Groovy tricks that dazzled you.

You have seen what the basic syntax of Groovy and the usage of the def keyword. Now it is time to explore Spock asserts.

2.2 Groovy Power Assert as a replacement for JUnit asserts

With the def mystery solved, the second striking feature of Spock tests is the lack of assert statements for evaluating their result. All JUnit tests end with one or more assert statements[11] where you define the expected result of the computation. If the expected result does not match the actual one, the test will fail. JUnit comes with an extensive API for assert statements and it is considered a good practice to create your own extensions, dealing with the business domain of your application.

I mentioned in the previous chapter that Spock does not have assert methods like JUnit In this section you will see how Spock deals with assertions and how they can help you in case of test failures. I will also continue with the general theme of this chapter - reducing the amount of needed code using Groovy instead of Java.

2.2.1 How Groovy handles asserts

In theory Groovy asserts function in a similar way to Java asserts. They expect a Boolean variable (or an expression that evaluates to Boolean), evaluate it and if it is true the assertion passes successfully. Spock runs assertions in the same way. If all assertion pass, then the unit test succeeds.

In practice however Java is very strict regarding true/false. Only Boolean variables can be tested for assertions. Groovy takes a more relaxed[12] approach on this because it allows all objects to be treated as Booleans.

Groovy treats all objects[13] as true unless:

1. the object is an empty string

2. the object is a null reference

3. the object is the zero number

4. the object is an empty collection (map, list, array etc)

5. the object is the false Boolean (obviously)

6. the object is a regex matcher that fails

Here are some examples with Groovy assertions demonstrating the rules of Groovy true/false:

Listing 2.9 Groovy can convert everything to a boolean

assert trueassert !false assert true || false #Aassert true && !false #A String firstName = "Susan"assert firstName #B def lastName = "Ivanova"assert lastName #B String empty = ""assert !empty #C Person person = new Person()assert person; #D Person nullReference = nullassert !nullReference; #E int answerToEverything = 42 #Fassert answerToEverything int zero=0 #Gassert !zero Object[] array= new Object[3]; #Hassert array Object[] emptyArray= new Object[0]; #Iassert !emptyArray Pattern myRegex = ~/needle/ #Jassert myRegex.matcher("needle in haystack") #Kassert !myRegex.matcher("Wrong haystack") #K println "Script has finished because all asserts pass"

#A Boolean variables work like Java

#B A non-empty string is true

#C An empty string is false

#D A valid reference is true

#E A null reference is false

#F A non-zero number is true

#G A zero number is false

#H A non-empty collection is true

#I An empty collection is false

#J Creation of regular expression

#K Regex is true if is matches at least once

If you run the example above, all asserts evaluate to true and the final line is printed in the console.

GROOVY TRUTH

The way Groovy handles true/false statements (called Groovy truth in Groovy parlance) can be used in Spock to trim the assert statement in a shorter form instead of converting them explicitly to Boolean variables.

Fun with Groovy truth

This is valid Groovy code: boolean flag = -45. Even though this line does not even compile in Java, in Groovy the number -45 is a non-zero number and therefore the variable flag is now true. Isn't that fun?

Here is a Spock example with both approaches, using both explicit Boolean evaluation (Java) and automatic "casting" to true/false (Groovy). The class under test is a trivial string tokenizer that counts word occurrences.

Listing 2.10 Groovy truth used in Spock tests

class GroovyTruthSpec extends spock.lang.Specification{ def "demo for Groovy truth"() { when: "a line of text is processed" WordDetector wordDetector = new WordDetector(); #A wordDetector.parseText("Understanding is a three edged sword: your side, their side, and the truth"); #B then: "word frequency should be correct" wordDetector.wordsFound() > 0 #C wordDetector.duplicatesFound().size() > 0 #C wordDetector.wordsFound() #D wordDetector.duplicatesFound() #E }}

#A Class under test is a Java class

#B Calling a Java method

#C Using Java like asserts with explicit conversion to boolean

#D Any positive number is automatically seen as true

#E Any non-empty collection is automatically seen as true

As an exercise you can locate some examples in chapter 1 where I have not used Groovy truth rules in the assert statements, and re-write them now that you know how Groovy can convert everything to a Boolean variable[14].

2.2.2 Using Groovy assertions in Spock tests

In the previous section you’ve seen how you can use Groovy truth to simplify your assert statements. I admit that this is another feature that looks mainly like sugar coating and you might not be impressed by the amount of code reduced. This is understandable, but the advantage of Groovy assertions is not really the application of Groovy truth rules.

The killer feature of Groovy (and therefore Spock) is the information it gives when an assert fails. You have seen some hints of this in chapter 1 using assertions that expect numbers (code listing 1.2 and 1.3) . In complex expressions Groovy shows all intermediate results. The next figure shows the Eclipse JUnit window in both cases but you get a similar output if run your unit tests in the command line or any other compatible tool with JUnit.

Figure 2.3 Groovy assert shows much more information than JUnit asserts

The magic of this feature is that it works with all objects and not just primitives. In Groovy there is no such distinction: everything is an object as far as Groovy is concerned.

What == means in Groovy

In Groovy the == operator is not testing identity like Java. It calls the equals() method of the object. Identity in Groovy is handled by the "is" keyword. Thus object1.is(object2) is the Groovy way of testing identity. You should be aware of this difference if you use objects in both sides of the assert statement (If you only perform simple assertions with scalar values -as you should- then this difference does not really matter)

Figure 2.4 is a more complex example of a failed Groovy asserts with lists. Again notice how Groovy shows all intermediate operations where JUnit just reports on the final result.

Figure 2.4 Groovy assert with lists compared to JUnit assert

Groovy Power assert works for your own objects as well, as shown figure 2.5

Figure 2.5 Groovy assert with the Java class shown in listing 2.10

This Spock feature is crucial for continuous delivery environments. As a developer you can understand exactly what goes wrong when a test fails. A well configured build server keeps all the results from unit tests and provides reports for the failed ones. Because Groovy (and in extension Spock) shows you the running context you can, in several cases, fix the bug right away instead of spending time with a debugger in order to reproduce it. For some enterprise environments where running an integration test is a lengthy process, this extra context for failing tests is a time saver that can easily persuade any Java developer to switch from JUnit.

I’ll show you how you can further enhance the output of Groovy Power asserts in Chapter 4. For now, I will continue with some useful Groovy features that have helped me in several Spock tests.

2.3 Groovy features useful to Spock tests

Now you have all the essential knowledge needed in order to write your own Spock assertions. For the rest of this chapter I’ll continue with the theme of reducing unit test code size with the expressiveness provided by Groovy compared to Java. All the following techniques are optional and you can still use normal Java code in your Spock tests if your organization needs a more gradual change. Each application is different and so it is hard to predict all ways where Groovy can help you with unit tests. The selection below is my personal preference.

2.3.1 Map-based constructors

If there is one feature of Groovy that I really adore, then that is object creation. Most unit tests create new classes either as test data or as services or helper classes used by the class under test. In a large Java application a lot of statements are wasted creating such objects. Here is a Java example where I need to test a class that takes as argument a list of persons:

Listing 2.11 JUnit test with multiple object creation statements

Employee trainee = new Employee(); #Atrainee.setAge(22); #Btrainee.setFirstName("Alice"); #Btrainee.setLastName("Olson"); #Btrainee.setInTraining(true); #B Employee seasoned = new Employee(); #Cseasoned.setAge(45); #Dseasoned.setFirstName("Alex"); #Dseasoned.setMiddleName("Jones"); #Dseasoned.setLastName("Corwin"); #D List<Employee> people = Arrays.asList(trainee,seasoned); Department department = new Department(); #E department.assign(people); #F [...rest of test]

#A Java object that will be used as test input

#B Filling of fields one by one

#C Second java object for test input

#D Filling of different fields one by one

#E class under test

#F test data is used

Java needs more than 10 statements to create the two objects that will be used for test input. This boilerplate code is too noisy when compared with the actual code that tests the department class.

EASY OBJECT CREATION WITH GROOVY CONSTRUCTORS

This is a well known problem to Java developers. Sometimes special constructors are created for business domain objects to allow for easy testing. I consider this an anti-pattern. This technique not only shifts verbosity from unit tests to core code, but also has its own shortcomings in case of multiple constructors. In the example above the Employee class would be polluted with a least two constructors (one that sets the trainee flag and one that ignores it).

Groovy comes to the rescue! Map-based constructors are autogenerated for your Java objects allowing your Spock tests to initialize any number of fields as well:

Listing 2.12 - Spock test with map-based constructors

when:Employee trainee = new #A Employee(age:22,firstName:"Alice",lastName:"Olson",inTraining:true)Employee seasoned = new #B Employee(middleName:"Jones",lastName:"Corwin",age:45,firstName:"Alex") List<Employee> people = Arrays.asList(trainee,seasoned) Department department = new Department() #Cdepartment.assign(people) #D[...rest of test]

#A Java object created with specific field values

#B Another Java object with different field values

#E class under test

#F test data is used

Here without changing a single line of Java code in the Employee class file, I have used the map based constructors where each field is identified by name and the respective value is appended after the semi-color character. Notice that the order of the fields and the set of the fields is completely arbitrary. With this technique [15]you can create a Java object with all possible combinations of its fields in any order that you like!

2.3.2 Using Maps and Lists in Groovy

The syntax shown in the previous section is not specific to constructors. This is the Groovy way of initializing a Map. You can use it for creating in a single statement a map. Here is an example.

Listing 2.13 - Groovy versus Java maps

Map<String,Integer> wordCounts = new HashMap<>();wordCounts.put("Hello",1); #AwordCounts.put("Java",1); #AwordCounts.put("World",2); #A Map<String,Integer> wordCounts2 = ["Hello":1,"Groovy":1,"World":2] #B

#A Manually filling a map (Java way)

#B Groovy can create and initialize a map

You can create any kind of Map like these even those where they keys and values are classes on their own. For Groovy it makes no difference.

Listing 2.14 - Groovy maps with non-scalar keys and values

Employee person1 = new Employee(firstName:"Alice",lastName:"Olson",age:30) #AEmployee person2 = new Employee(firstName:"Jones",lastName:"Corwin",age:45) #A Address address1 = new Address(street:"Marley",number:25) #AAddress address2 = new Address(street:"Barnam",number:7) #A Map<Employee,Address> staffAddresses = new HashMap<>();staffAddresses.put(person1, address1); #BstaffAddresses.put(person2, address2); #B Map<Employee,Address> staffAddresses2 = [(person1):address1,(person2):address2] #C

#A Creating a Java object using map based constructors

#B Filling a map manually (the Java way)

#C Creating and initializing a Map (the Groovy way)

As can be seen in listing 2.13 when classes are used for the keys of the Map, you need to put extra parentheses. If you don't then they are assumed to be Strings. Also this concise Groovy syntax creates by default a LinkedHashMap.

In a similar way to Maps, Groovy supports a concise syntax for lists as well. If you have ever wondered why it is so easy to create an array in Java in a single statement but not a list then you will be happy to discover that Groovy has you covered. The following listings shows the comparison:

Listing 2.15 - Groovy versus Java lists

List<String> races = Arrays.asList("Drazi", "Minbari", "Humans") #A List<String> races2 = ["Drazi", "Minbari", "Humans"] #B assert races == races2 #C String[] racesArray = ["Drazi", "Minbari", "Humans"] #DString[] racesArrayJava = {"Drazi", "Minbari", "Humans"} #E

#A Creating a list with data in Java

#B Creating a list with data in Groovy

#C The == operator tests equality in Groovy and not identity. This assert passes

#D Creating an array with data in Groovy

#E This is valid Java, but invalid Groovy.

Because the syntax of arrays and lists is similar in Groovy, you might find yourself using arrays less and less as you gain experience with Groovy. Also notice that the usual way of declaring arrays in Java is one of the few cases where valid Java is invalid Groovy. If you try to create an Array in Groovy using the Java notation you will get an error because Groovy uses the same syntax for closure as you see later on in this chapter.

Using the knowledge of the last sections you can completely rewrite the JUnit test from listing 2.11 as follows:

Listing 2.16 Creating Groovy lists and maps in test code

List<Employee> people = [ #A new Employee(age:22,firstName:"Alice",lastName:"Olson", inTraining:true), new Employee(middleName:"Jones",lastName:"Corwin",age:45, firstName:"Alex") ] Department department = new Department() #Bdepartment.assign(people) #C[...rest of test]

#A Groovy initialization of list using map based constructor objects

#B Java class under test

#C Usage of test data

By following Groovy conventions, I’ve replaced 11 Java statement with one. The unit test is much more readable because it is clearly split as far as test data creation and test data usage are concerned.

ACCESSING LISTS IN GROOVY USING ARRAY INDEX NOTATION

So far I‘ve only demonstrated how maps and lists are initialized. Let's see how Groovy improves their usage as well.

Listing 2.17 Using Groovy lists

List<String> humanShips = ["Condor","Explorer"] #Aassert humanShips.get(0) == "Condor" #Bassert humanShips[0] == "Condor" #C humanShips.add("Hyperion") #DhumanShips << "Nova" << "Olympus" #Eassert humanShips[3] == "Nova"assert humanShips[4] == "Olympus" humanShips[3] = "Omega" #Fassert humanShips[3] == "Omega"

#A Creating a list with two elements

#B Java way of getting an element

#C Groovy way of accessing list

#D Java way of adding new element

#E Groovy way of adding elements

#F Groovy way of replacing an element

Notice how writing and reading to a list uses the same syntax and only the context defines the exact operation. Again this syntax is optional and you are free to use the Java way of doing things even in Spock tests.

Groovy offers the same array-like syntax for maps as well as shown below:

Listing 2.18 Using Groovy maps

Map<String,String> personRoles = [:] #ApersonRoles.put("Suzan Ivanova","Lt. Commander") #BpersonRoles["Stephen Franklin"]= "Doctor" #C assert personRoles.get("Suzan Ivanova") == "Lt. Commander" #Dassert personRoles["Stephen Franklin"] == "Doctor" #E personRoles["Suzan Ivanova"]= "Commander" #Fassert personRoles["Suzan Ivanova"] == "Commander"

#A Creating an empty map in Groovy

#B Java way of inserting into map

#C Groovy way of inserting into map

#D Java way of accessing map

#E Groovy way of accessing map

#F Groovy way or replacing element

Lists and maps are one of the many areas where Groovy augments existing Java collections. Groovy comes with its own GDK that sits on top of the existing JDK. You should spend some time to explore the GDK according to your own unit tests and discover more ways to reduce your existing Java code. For more details see http://beta.groovy-lang.org/docs/latest/html/groovy-jdk/.

So far we’ve seen how Groovy enhances classes, fields and collections. Let's see how Groovy Strings compare to Java Strings.

2.3.3 Interpolating text with Groovy Strings

I have already demonstrated Groovy Strings (GStrings) in the beginning of this chapter where I took a single Java class and converted it to idiomatic Groovy in a gradual way. At the most basic case they allow for quick text templates of object properties, but they can handle full expressions as shown below.

Listing 2.19 Using Groovy Strings

SimpleDepartment sales = #A new SimpleDepartment(name:"Sales",location:"block C")SimpleEmployee employee = #A new SimpleEmployee(fullName:"Andrew Collins",age:37,department:sales) System.out.println("Age is "+employee.getAge()) #Bprintln "Age is $employee.age" #C System.out.println("Department location is at "+employee.getDepartment().getLocation()) #Bprintln "Department location is at $employee.department.location" #C println "Person is adult ${employee.age > 18}" #Dprintln "Amount in dollars is \$300" #Eprintln 'Person is adult ${employee.age > 18}' #F

#A Creating Java objects with maps based constructors

#B Java way of accessing fields

#C Groovy way of accessing fields

#D Using {} for full expressions

#E Escaping the $ character

#F Disabling evaluation altogether with single quotes

When run, this code will print:

>groovy GroovyStrings.groovyAge is 37Age is 37Department location is at block CDepartment location is at block CPerson is adult trueAmount in dollars is $300Person is adult ${employee.age > 18}

Groovy String interpolation is certainly powerful, but for unit tests most interesting is their multiline capability. Similar to other scripting languages, Groovy allows you to split a big string with newlines:

Listing 2.20 Using Groovy multiline strings

def "Another demo for Groovy multiline strings"() { when: "a paragraph is processed" String input = '''I want you to know you were right. I didn't want \ to admit that. Just pride I guess. You get my age, you \ get kinda set in your ways. It had to be \ #A done. Don't blame yourself for what happened later.''' WordDetector wordDetector = new WordDetector(); wordDetector.parseText(input); #B then: "word count should be correct" wordDetector.wordsFound() == 34 }

#A Creation of a multi-line string

#B Using the multi-line string

This is a great feature for those unit tests that require text input of 3-4 lines that can be embedded directly on the source file itself. Multi-line strings also support text interpolation if you use double quotes instead of single, but inside unit tests it is better if they are pure text (without text interpolation) for clarity reasons. For bigger sizes of text I also advise using a separate text file as demonstrated in the next section.

2.4 Reading a test dataset from an external source

One of the challenges I face when creating a new unit test (especially in the case of Test Driven Development where the test is created before the implementation code) is finding correct test input. For basic unit tests where only a single class is tested, you might get away with trivial data created on the spot.

For integration tests however, where multiple code modules are tested, your selection of test data needs more thought. Once you have enough tests for the happy paths of your code, it is time to examine all corner cases and strange scenarios. Creating effective test data is a separate skill on its own, but a good source of such data can be found on an existing running system. A lot of times test data can also be obtained from issues reported by the users of the software. These types of data are as real as they get so they are excellent candidates for your unit tests.

Unfortunately several times useful test data is trapped in the transport medium (e.g. XML files) that must be processed before they can be used directly in a unit test. Groovy comes with excellent facilities for extracting test data from external files, and you should take advantage of these techniques in your Spock tests. Using the Java approach will also work, but again in a much more verbose way.

2.4.1 Reading a text file

Reading a text file in Java usually required a basic understanding of buffered readers or any other Java file API that was added with each new Java version [16]. Groovy however does away with all the unneeded craft and allows you to read a file in the simplest way possible.

String testInput = new File("src/test/resources/quotes.txt").text

A normal File is opened. Groovy adds the .getText() method that reads its text. You could also specify the encoding if it is not the default. This simplicity is very handy because it can be used straight in a Spock test.

Listing 2.21 Reading test data from a file in a Spock test

def "demo for reading a text file"() { when: "a paragraph is processed" WordDetector wordDetector = new WordDetector(); String inputText = new File("src/test/resources/quotes.txt").text #A wordDetector.parseText(inputText); then: "word frequency should be correct" wordDetector.wordsFound() == 78 } def "demo for reading a text file line by line"() { when: "a paragraph is processed" List<String> inputText = new File("src/test/resources/quotes.txt").readLines() #B WordDetector wordDetector = new WordDetector(); for(String line:inputText) { wordDetector.feedText(line) } then: "word count should be correct" wordDetector.wordsFound() == 78}

#A Reading the whole text file

#B Reading a file line by line

Notice the expressive code. There is no boiler plate for auto-closing streams or anything like that. I will show you more examples with CSV files in chapter 5, where Groovy code is both shorter and easier to understand than the Java way. In chapter 5 I will show you data-driven Spock tests where the same test is evaluated for multiple (similar) sets of input test data.

2.4.2 Reading an XML file

XML is the lingua franca of large enterprise applications. One of the original marketing points of Java was the handling of XML files. Business web services usually produce some sort of XML dialect and several custom file formats are XML files under the hood. As with Java, Groovy supports several ways, but explaining them all is outside the scope of this chapter.

I will demonstrate the XMLSlurper way of reading XML files with Groovy. You can use this technique either when you want to read test data from an XML file, or when your Java class writes XML and you want to quickly verify its correctness[17].

Let's assume that my XML file is the following:

<staff> <department name="sales"> <employee> <firstName>Orlando</firstName> <lastName>Boren</lastName> <age>24</age> </employee> <employee> <firstName>Diana</firstName> <lastName>Colgan</lastName> <age>28</age> </employee> </department></staff>

Here is the respective Groovy code:

Listing 2.22 Reading XML in Groovy

def xmlRoot = new XmlSlurper().parse('src/main/resources/employee-data.xml') #Aassert xmlRoot.department.size() ==1 #Bassert xmlRoot.department.@name =="sales" #Cassert xmlRoot.department.employee.size() ==2 #Bassert xmlRoot.department.employee[0].firstName =="Orlando" #Dassert xmlRoot.department.employee[0].lastName =="Boren"assert xmlRoot.department.employee[0].age ==24assert xmlRoot.department.employee[1].firstName =="Diana" #Eassert xmlRoot.department.employee[1].lastName =="Colgan"assert xmlRoot.department.employee[1].age ==28

#A Creation of the XmlSlurper object

#B Checking the number of children XML nodes

#C Accessing an XML property

#D Accessing XML content of the first child

#E Accessing XML content of the second child

Here you can see the expressive Groovy Power in all its glory. Reading the XML file is a single line. Then you just use Xpath-like expression to retrieve actual XML content. I won't even bother to write the Java code for the same example. Xml reading (and writing) in Java has always contained boilerplate code, that is taken for granted by Java developers. Groovy discards all this and keeps only the substance.

2.4.3 Reading a JSON file

Groovy reads JavaScript Object Notation (JSON) in a similar way to how it reads XML. XML might be dominant in legacy enterprise applications, but newer web services tend to use JSON. Groovy covers them both with the same ease.

Let's assume that my JSON file is the following:

{ "staff": { "department": { "name": "sales", "employee": [ { "firstName": "Orlando", "lastName": "Boren", "age": "24" }, { "firstName": "Diana", "lastName": "Colgan", "age": "28" } ] } }}

Here is the respective Groovy code (almost the same as the XML one):

Listing 2.23 Reading JSON in Groovy

def jsonRoot = #A new JsonSlurper().parse(new File('src/main/resources/employee-data.json'))assert jsonRoot.staff.department.name =="sales" #Bassert jsonRoot.staff.department.employee.size() ==2 #Cassert jsonRoot.staff.department.employee[0].firstName =="Orlando" #Dassert jsonRoot.staff.department.employee[0].lastName =="Boren"assert jsonRoot.staff.department.employee[0].age =="24"assert jsonRoot.staff.department.employee[1].firstName =="Diana" #Eassert jsonRoot.staff.department.employee[1].lastName =="Colgan"assert jsonRoot.staff.department.employee[1].age =="28"

#A Creation of the JsonSlurper object

#B Accessing Json field

#C Checking the size of JSon array

#D Accessing first element of the array

# E Accessing second element of the array

It is very easy to obtain test data from JSon with Groovy. The syntax is even simpler than XML in some ways.

2.5 Advanced Groovy features useful to testing

I hope that this chapter served as a gentle introduction to Groovy, and that if you were scared by the syntax of Spock tests in chapter 1, you are now more confident with how things work. In several ways, Groovy just simplifies Java code by leaving only the gist and discarding the bloat.

Explaining all things Groovy can do in a single chapter is impossible. Groovy has several advanced constructs for core programming that blow away any Java code you have already seen. In this last section I will show you some more advanced concepts that you might use in your Spock tests.

Do not be alarmed if the code shown is more complex than the previous examples. You can skip this part and come back again when you have more experience with Groovy and become comfortable with Spock tests. That being said, the techniques shown below are in no way essential to Spock tests. They have their use at times, but you should always make sure that your unit tests are not over-engineered.

Do not fall into the trap of using cool Groovy tricks in Spock tests just to impress your Java friends! Keep Spock tests simple and understandable.

2.5.1 Groovy closures

The official Groovy book assigns a whole chapter to explain closures, so I am not even going to try to do the same in these paragraphs. You might already know closures from other programming languages[18]. If not, then spend some time to research them because they are universally helpful (even outside the context of Groovy). Closures are in many ways similar to methods. Unlike Java methods, they can be passed around as arguments to other methods or become partially evaluated instead of called directly. Java 8 also comes with lambda expressions which serve as a stepping stone to functional programming concepts. If you already worked with Java 8, then Groovy closures will come natural to you.

Closures in Groovy are denoted by the -> character and are contained in {}. Here are some examples:

Listing 2.24 Groovy closures

Closure simple = { int x -> return x * 2} #Aassert simple(3) == 6 #B def simpler = { x -> x * 2} #Cassert simpler(3) == 6 def twoArguments = { x,y -> x + y} #Dassert twoArguments(3,5) ==8

#A A Closure with full Groovy notation that doubles its integer argument

#B Using the closure as a method

#C Same closure with concise Groovy. Return is optional as well

#D A Closure with two arguments

Closures are the Swiss army knife of Groovy. They are used almost everywhere and it is hard to deal with Groovy code without stumbling on them. Prior to Java 8 they were one of the main advantages of Groovy over Java, and even after Java 8 they still offer great value and simplicity. Closures are so powerful in Groovy, that you can use them directly to implement interfaces or as exit points in switch statements.

The Groovy GDK augments the existing JDK with several new methods that accept closures for arguments. For example a handy Groovy method for unit testing is the every() method available in collections. Assume you have a Java class that gets a list of image names from a text file and returns only those that end in a specific file extension. Closures can be employed in the Groovy assert as shown below:

Listing 2.25 Using Groovy closures in Spock tests

def "Testing Jpeg files"() { when: "only jpeg files are selected from a list of filenames" FileExtensionFilter myFilter = new FileExtensionFilter() #A myFilter.addValidExtension("jpeg") #B myFilter.addValidExtension("jpg") #B List<String> testInput = ["image1.jpg","image2.png","image3.jpeg", "image4.gif","image5.jpg","image6.tiff"] #C List<String> result = myFilter.filterFileNames(testInput) #D then: "result should not contain other types" result.every{ filename -> filename.endsWith("jpeg") || filename.endsWith("jpg")} #E}

#A Creation of Java class under test

#B Setup file extensions that will be accepted

#C List that will be passed to class under test

#D Result of method call is another list

#E Using a closure to test each element of the list

In this Spock test the assertion is a single line because all elements of the list are checked one by one automatically by the closure. The closure takes as argument a string and returns true if the string ends in jpg (using both three and four letter notations).

Other methods useful to unit tests (apart from every() shown above) are:

· any(closure) - returns true if at least one element satisfies closure

· find(closure) - finds first element that satisfies closure

· findAll(closure)- finds all elements that satisfy closure

You should consult the Groovy official documentation for more details at http://groovy.codehaus.org/GDK+Extensions+to+Object.

2.5.2 Creating test input with ObjectGraphBuilders

One of the arguments against unit tests (and integration tests in particular) is the effort required to come up with "real" test data. In a complex business application the data that is moved around is rarely a single Object. Most times it is a collection of objects, a tree-structure, a graph or any other complex structure.

This makes writing integration tests a lengthy process as about 80% of the code can be consumed just to create the test input for the class under test. Test input code generation is one of the first candidates for code re-use inside unit test. In sufficiently large enterprise projects test input generation might need a separate code module on its own outside of production code.

Groovy to the rescue! Groovy comes with a set of builders that allow you to create test data using a fancy DSL. Instead of creating the data manually you just declare the final result. As an example assume that your domain contains the following classes:

Listing 2.26 - Domain Classes in Java

public class AssetInventory { private List<Ship> ships = new ArrayList<>(); #A [...getters and setters here...]} public class Ship { private String name; private List<CrewMember> crewMembers = new ArrayList<>(); private String destination; private List<Cargo> cargos= new ArrayList<>();[...getters and setters here...]} public class CrewMember { private String firstName; private String lastName; private int age;[...getters and setters here...]}public class Cargo { private String type; private CargoOrder cargoOrder; #B private float tons;[...getters and setters here...]}public class CargoOrder { private String buyer; private String city; private BigDecimal price;[...getters and setters here...]}

#A Lists are already initialized

#B name of fields is the same as class name

This is a typical business domain. If you look close enough you will see that is follows some certain rules:

· Each child field has the same name of the class (CargoOrder cargoOrder)

· Each list is already initialized

· Each list fields has the plural name of its class (Ship -> ships)

Because of this rules it is possible to create a deep hierarchy of this domain using an ObjectGraphBuilder as shown below:

Listing 2.27 - Using a Groovy builder for quick object creation

ObjectGraphBuilder builder = new ObjectGraphBuilder() #Abuilder.classNameResolver = "com.manning.spock.chapter2.assets" #B AssetInventory shipRegistry = builder.assetInventory() { #C ship ( name: "Sea Spirit", destination:"Chiba") { crewMember(firstName:"Michael", lastName:"Curiel",age:43) #D crewMember(firstName:"Sean", lastName:"Parker",age:28) crewMember(firstName:"Lillian ", lastName:"Zimmerman",age:32) cargo(type:"Cotton", tons:5.4) { cargoOrder ( buyer: "Rei #E Hosokawa",city:"Yokohama",price:34000) } cargo(type:"Olive Oil", tons:3.0) { cargoOrder ( buyer: "Hirokumi &nbsp. Kasaya",city:"Kobe",price:27000) } } ship ( name: "Calypso I", destination:"Bristol") { crewMember(firstName:"Eric", lastName:"Folkes",age:35) crewMember(firstName:"Louis", lastName:"Lessard",age:22) cargo(type:"Oranges", tons:2.4) { cargoOrder ( buyer: "Gregory &nbsp. Schmidt",city:"Manchester",price:62000) } } ship ( name: "Desert Glory", destination:"Los Angeles") { crewMember(firstName:"Michelle", lastName:"Kindred",age:38) crewMember(firstName:"Kathy", lastName:"Parker",age:21) cargo(type:"Timber", tons:4.8) { cargoOrder ( buyer: "Carolyn &nbsp. Cox",city:"Sacramento",price:18000) } }} assert shipRegistry.ships.size == 3assert shipRegistry.ships[0].name == "Sea Spirit"assert shipRegistry.ships[1].crewMembers.size == 2assert shipRegistry.ships[1].crewMembers[0].firstName == "Eric"assert shipRegistry.ships[2].cargos[0].type=="Timber"assert shipRegistry.ships[2].cargos[0].cargoOrder.city=="Sacramento"

#A Creating the builder

#B Instructing the builder of that domain java package

#C Using the builder for the top level object

#D Map based constructors

#E Children node automatically created and attached to parent

Here I have created a ship registry with 3 ships, 7 people and 4 cargo order all in about 30 lines of Groovy code. Creating the same tree with Java code would need more than 120 lines of code (for brevity reasons you can find the code in the source of this book). Groovy gives me in this particular case a 75% reduction of code lines.

The other important point is the visual overview of the tree structure. Because the ObjectGraphBuilder offers a declarative DSL for the object creation, you can get an overview of the tree structure just by looking at the code.

If your domain classes do not follow the rules outlined above you can either change them (easiest) or inject the ObjectBuilder with custom resolvers to override default behavior. Consult the official Groovy documentation for examples with custom resolvers. By default the ObjectGraphBuilder will treat as plural (for collections) the classname plus s (ship becomes ships). It also supports special cases with words that end in "y" (daisy becomes daisies, army becomes armies etc).

2.5.3 Creating test input with Expandos

Spock includes comprehensive mocking and stubbing capabilities as you will see in chapter 6. For simple cases you can also get away using vanilla Groovy. Groovy really shines when it comes to dynamic object creation.

As a final example of Groovy Power I will demonstrate how Groovy can create objects on the spot. Assume that you have an interface of this DAO:

public interface AddressDao { Address load(Long id);}

You also have a business service that uses this dao as follows:

public class Stamper { private final AddressDao addressDao; public Stamper(AddressDao addressDao) { this.addressDao = addressDao; } public boolean isValid(Long addressID) { Address address = addressDao.load(addressID); return address.getStreet()!= null && address.getPostCode()!= null; }}

This business service checks Address objects (a POJO) and considers them valid if they have both a street and a post code. You want to write a Spock test for this service. Of course, you could mock the AddressDao as we will show in chapter 6. But with Groovy you can simply create dynamically an object that mimics this service:

Listing 2.28 - Using Expandos to mock interfaces

def "Testing invalid address detection"() { when: "an address does not have a postcode" Address address = new Address(country:"Greece",number:23) #A def dummyAddressDao = new Expando() #B dummyAddressDao.load = { return address} #C Stamper stamper = new Stamper(dummyAddressDao as AddressDao) #D then: "this address is rejected" !stamper.isValid(1) #E} def "Testing invalid and valid address detection"() { when: "two different addresses are checked" Address invalidAddress = new Address(country:"Greece",number:23) #F Address validAddress = new Address(country:"Greece", #F number:23,street:"Argous", postCode:"4534") def dummyAddressDao = new Expando() dummyAddressDao.load = { id -> return #G id==2?validAddress:invalidAddress} Stamper stamper = new Stamper(dummyAddressDao as AddressDao) then: "Only the address with street and postcode is accepted" !stamper.isValid(1) #H stamper.isValid(2) #H}

#A Creation of test data

#B Creation of empty Groovy dynamic object

#C Creating the load method dynamically

#D Using the Groovy dynamic object in place of the Java interface

#E Tricking the class under test to use the expando - the argument is irrelevant

#F Covers both cases

#G Using the closure argument to return either test input

#H Call class under test - argument is used in expando closure

The magic line here is the one with the as keyword. This keyword performs casting in Groovy but in a much more powerful way than Java. The Expando class has no common inheritance with the AddressDao, yet it can still work as one because of duck typing (both objects have a load() method and that is enough for Groovy).

While this is a common use of Expandos, they have several other uses that you might find interesting. The combination of duck typing and dynamic object creation will certainly amaze you[19]. Here is another example where I use an Expando for integer generation (that could be used as test data in a Spock test):

Listing 2.29 - Using a Groovy expando as test data generator

Expando smartIterator = new Expando() #AsmartIterator.counter = 0; #BsmartIterator.limit = 4; #CsmartIterator.hasNext = { return counter < limit} #DsmartIterator.next = {return counter++} #DsmartIterator.restartFrom = {from->counter = from} #E for(Integer number:smartIterator as Iterator<Integer>) #F{ println "Next number is $number"} println "Reset smart iterator"smartIterator.restartFrom(2)#G for(Integer number:smartIterator as Iterator<Integer>) #H{ println "Next number is $number"}

#A Creation of empty Groovy dynamic object

#B Creation of field that will hold next number

#C Creation of field that will hold max value returned

#D Imitation of Iterator interface method

#E Adding custom method not defined in iterator interface

#F Using the Expando in the place of an iterator

#G Calling the custom method to change the state of the iterator

#H Using the Expando after resetting it.

when you run this code you will get the following:

>groovy ExpandoDemo.groovyNext number is 0Next number is 1Next number is 2Next number is 3Reset smart iteratorNext number is 2Next number is 3

After the iterator is restarted I can use it again as normal even though the previous run had reached the limit of numbers generated. Notice also that I did not implement in the Expando class the remove() method defined by the iterator Java interface. My code does not use it so the Expando object does not need to declare it. But because of duck typing my Expando still passes as an Iterator even though it only implements two out of three required methods.

2.6 Summary

· Groovy is a language that also runs in the JVM

· Groovy source is compiled into Java bytecode

· Using Java classes from Groovy code happens with the new keyword exactly like Java

· Groovy is mostly compatible with Java syntax

· In Groovy classes are public by default and fields private by default

· Groovy autogenerates getters and setters

· In Groovy semicolons and the return keyword are optional

· Groovy supports optional typing where you can declare the type of a variable (like Java)

· or use the def keyword to leave it to the runtime

· Groovy treats all objects as "true" unless the object is an empty string, an empty collection, 0, null or false.

· Spock use Groovy assertions instead of JUnit assert calls

· Groovy allows you to create object by using maps of fields/values inside the constructor

· Groovy Strings employ automatic templating similar to JSTL

· Groovy comes with extensive utilities to read XML and JSON files

· Groovy supports closures which can be used to reduce the code lines in assert statements

· An ObjectGraphBuilder can be used to create quickly a tree like structure of your business domain

· You can use expandos to dynamically create Groovy Objects during runtime

[7] http://en.wikipedia.org/wiki/Duck_typing

[8] This number is not scientific in any way.

[9] It is also possible to access Groovy code from Java code, but this is not needed for Spock testing. See http://groovy.codehaus.org/Embedding+Groovy for more details.

[10] or optionally typed because Groovy still supports the Java way of explicit types

[11] Not having an assert (or verify) statement is a huge anti-pattern because the test never fails.

[12] or error-prone if you wish. Some of the old C traps are now possible with Groovy as well (but not all)

[13] closures are also "true"

[14] Groovy Strings also get an additional toBoolean() method that treats only "true", "y" and "1" as true

[15] Groovy supports even more concise constructors. They sacrifice clarity so I refrain from showing them here.

[16] or coming from an external library such as Apache Commons

[17] For more complex XML verification cases you can also use a dedicated XML diff library like XMLUnit

[18] You may have seen function pointers, function references, higher order methods or code blocks in other languages. They are not strictly speaking the same thing as closures but the main concepts are similar.

[19] Just don't get carried away. Expando overuse is not a healthy habbit.