Spock Tutorial: Testing With Spock And Groovy

Hands-on Spock Tutorial Series: Testing with Spock framework and Groovy Programming Language

This series of tutorials would completely enrich your knowledge on Spock Framework.

Simple and clear examples have been included in each tutorial for your easy understanding of the concept.

Get Ready To Learn Spock For Free!!

Spock And Groovy

List of All the Spock Tutorials in this Series:

Learn Spock in detail with the help of this Intensive Spock Training series for beginners and experienced professionals.


Overview of Tutorials in Spock Series

Tutorial_NumWhat You Will Learn
Tutorial #1Introduction to Spock and Groovy

This introductory tutorial will explain all about Spock, which is a test framework that’s built on top of Groovy. It enforces BDD at the core and ensures all tests written using the framework follows the BDD conventions.
Tutorial #2Writing Unit Tests with Spock

In this tutorial, we will walk through all the details/steps that are required to get started with Unit testing in Spock along with simple examples.
Tutorial #3Parameterized Testing With Spock

This tutorial will clearly explain what parameterized tests are and how you can leverage the in-built features of Spock to achieve data-driven testing.
Tutorial #4Spock Mocking and Stubbing

This Spock tutorial will explain in detail about Mocking and Stubbing which are one of the most essential building blocks of extensive Unit tests.
Tutorial #5Spock with Selenium Functional Test

Learn how to use Spock for Integration testing (like rest services) and for functional testing from this informative tutorial. For Example, Integrating Spock with Selenium.
Tutorial #6Spock Interview Questions

This tutorial includes a list of the Most popular Spock Interview Questions with Answers and examples. These questions would indeed guide anyone to clear the spock interview successfully at the first attempt.

What is Spock?

Spock is a test framework that’s built on top of Groovy. It enforces BDD at the core and ensures if all tests written using the framework follow the BDD conventions.

Also, unlike JUnit, Spock has its own Mocking and test double libraries as well as full support for parameterized test scenarios.

It is due to this complete package in self, the Spock specifications are super readable and expressive and as a result of which they make the test to achieve more and more of what it was intended for reducing the cliché boilerplate code.

In spite of all these cool features, Spock tests are runnable using the existing JUnit test runner & the existing command line/build tools like Maven and Gradle, which make it even more compelling to use. In a nutshell, Spock combines all the good features of JUnit, BDD (frameworks like JBehave & Cucumber) as well as mocking.

We will take a look at a couple of examples illustrating each of these features in the further sections.

Watch the Spock and Groovy Video Tutorial

What is Groovy?

Groovy is a scripting language for Java platform.

Some of the main features of groovy include:

#1) It can be used as dynamically typed (where a variable can hold any type of data) as well as statically typed (which enforces strongly typed constructs on variables holding data).

Example: We have assigned array and map in the same way and internally groovy determines the type and handles it appropriately.

 
def listType = [1,2,3]
def mapType = ["red":2,"green":3]

println(listType.getClass())
println(mapType.getClass())

The output of the above code sample is:

class java.util.ArrayList
class java.util.LinkedHashMap

#2) All valid Java code is a valid Groovy code too (but not the other way round as it has additional features as well).

#3) Other features include meta-programming, closures, static type checking, etc.

#4) Unlike Java semicolons are optional in groovy and the primitive types are considered as objects by default.

As this tutorial series is more focused on Spock, we’ll just learn those Groovy features that are essential for authoring Spock based test specifications.

Getting Started with Spock

In order to get started, let’s see, what libraries are required depending on what build system you are using (ex. Gradle / maven).

For Maven based projects

Maven projects will need to include a plugin for compiling Gradle code as well as a surefire plugin in order to run groovy based specifications. In addition to this groovy & Spock, dependencies should also be added.

<plugins>
                  <plugin>
                         <groupId>org.codehaus.gmavenplus</groupId>
                         <artifactId>gmavenplus-plugin</artifactId>
                         <version>1.5</version>
                         <executions>
                               <execution>
                                        <goals>
                                                <goal>testCompile</goal>
                                       </goals>
                               </execution>
                          </executions>
               </plugin>
               <plugin>
                      <artifactId>maven-surefire-plugin</artifactId>
                      <version>2.18.1</version>
                      <configuration>
                              <useFile>false</useFile>
                              <includes>
                                     <include>**/*Spec.java</include>
                              </includes>
                       </configuration>
               </plugin>
</plugins>
<dependency>
           <groupId>org.spockframework</groupId>
           <artifactId>spock-core</artifactId>
           <version>1.3-groovy-2.5</version>
           <scope>test</scope>
</dependency>

For Gradle based Projects

For a sample gradle file as below, the most important requirements include gradle plugin and the dependencies for groovy for code and test.

plugins {
      id 'java'
       id 'groovy'
}

repositories {
        mavenCentral()
}

dependencies {
         compile "org.codehaus.groovy:groovy-all:2.4.8"
         testCompile "org.spockframework:spock-core:1.1-groovy-2.4"
}

Anatomy of a Spock Specification

Spock tests can be written for any language that runs on JVM. This means that even if your application code is in Java or Scala or Kotlin etc., you can still choose to write your unit/integration tests in Spock (over others like JUnit, JBehave, etc.).

Spock test classes are called “Specifications” (Similar to Specs in BDD world) and you can extend the “Specification” class of the Spock framework. (Specification is the base class of the Spock framework).

Each Spec file can contain multiple tests (similar to a JUnit test class file) and each test can optionally contain the BDD blocks i.e. given, when and then. This is similar to other BDD frameworks, where each of these sections can be correlated to Arrange, Act and Assert sections in the JUnit tests respectively.

Below is a block diagram depicting the hierarchy of Spec and tests.

hierarchy of Spec and tests

Let’s see how a sample specification looks in the code:

import spock.lang.Specification
class SampleSpec extends Specification {

def "check case-insensitive equality of 2 strings"() {
            
given:
    String str1 = "hello"
    String str2 = "HELLO"
            
when:
     str1 = str1.toLowerCase()
     str2 = str2.toLowerCase()
            
then:
      str1 == str2

}

def "check addition of 2 numbers"() {
       
given:
       int input1 = 10
       int input2 = 25
   
when:
        int result = input1 + input2
        
then:
        result == 35
}
} 

Few important points to note here:

#1) Look at the name of the test scenarios (the string after the def keyword): “check case-insensitive equality of 2 strings”. These are plain English strings and this makes the test names quite readable and gives a real sense to test as to what it achieves.

Compare it to the usual JUnit test where the test name will look as something like c.

caseEquality_withValidInput_shouldBeEqual()

#2) Given, when and then blocks are equivalent to Arrange, Act and Assert. Out of these look at the then (or assert block) which implies equality assertion and avoids all boilerplate code associated with assertions.

Example, An assertion in JUnit would have looked as shown below:

@Test
public void compareStrings_withValidInput_shouldReturnSuccess() {
     
// Arrange
     String str1 = "hello";
     String str2 = "HELLO";

// Act
     str1 = str1.toLowerCase();
     str2 = str2.toLowerCase();

// Assert
   Assert.assertEquals(str1,str2);
} 

As you can see from the above, the Spock tests make the tests look less verbose as well as avoid all boilerplate code in assertions (and setup, etc.)

Spec Block Descriptions

For each of the individual blocks in a test, you can choose to provide block description as a string to provide more details about the block that’s getting executed. This is helpful for providing a more verbose structure to the test.

Let’s see an Example below:

 
def "check case-insensitive equality of 2 strings"() {
                  
given: "two input strings"
        String str1 = "hello"
        String str2 = "HELLO"
                 
when: "strings are lowercased"
        str1 = str1.toLowerCase()
        str2 = str2.toLowerCase()
                 
then: "equal strings should return success"
        str1 == str2
} 

Important Tips

#1) All the blocks in a Spock based spec are optional. However, if present “when” and “then” should appear together in sequence.

#2) If you just need to validate an assertion (and you don’t have a need of when block), you can use “expect” block. It can be used to assert pre-conditions even before when and then blocks (and can be used multiple times in a test).

Let’s see a sample usage of expect like validating the pre-condition before executing the “when” block.

def "check addition of 2 numbers"() {
                  
given:
     int input1 = 10
     int input2 = 25
                   
expect:
       input1.getClass().toString() == "class java.lang.Integer"
       input2.getClass().toString() == "class java.lang.Integer"
       input1 <= Integer.MAX_VALUE input1 >= Integer.MIN_VALUE
                  
when:
      int result = input1 + input2
                 
then:
      result == 35
} 

As shown above, the expect block is trying to assert the class value of the input fields as well as the value of one of the inputs to lie within the range.

Conclusion

In this Spock tutorial, we have covered the basics of Groovy programming language, along with the anatomy or basic building blocks of a Spock Specification.

We created a sample project with the required dependencies in order to write groovy based Spock specifications and wrote a sample specification.

In the other tutorials in this series, we will delve deeper into the features provided by the Spock framework and get to know how they make use of groovy language to create clean, and readable test specifications.

Stay tuned to our upcoming Spock tutorials to know more about Test fixtures, Assertions and Reporting in Spock.

NEXT Tutorial