Free webinar: Spock: ‘Test Fast & Prosper!’


Groovy
Martin Müller portrait
Martin Müller
Java / Kotlin Team Lead
14 Feb 2022
181
Technology topics
#Java

I use Java a lot and I like the language. But sometimes expressing my ideas in Java in a simple and natural way can be a bit cumbersome. I’m forced to wrap them into anonymous inner classes or to create some complex support structure to make them live - like in the joke where you want to build a Horse… but first you need a HorseFactory!

And there is one more thing. Creating quite simple structures in Java still requires a significant amount of code. This can be inconvenient at any time but especially during testing. I want my tests to be clear and simple. Preparation of testing objects should not take 50 lines of code and what and why is the test doing should be obvious for every reviewer. Good and expressive tests are like documentation of our production code. It can really tell you a lot about the purpose of all those classes in your project.

Groovy Goodness

Do you know Groovy? It is a powerful Java-compatible language; meaning that it can coexist with Java in your projects and do some special things. Do you want to initialize a Map in one line? No problem. Are you a fan of Elvis? We have it. There is also support for Closures and much more.

Groovy dynamic typing makes it flexible, but I do not like it for production development. Java programmers just don’t want to see compile-time kind of exceptions being thrown in at runtime, such as using a wrong argument type in calling your method from Groovy.

Anyway, Groovy is great for testing. Where Java is verbose, Groovy is clear and simple. Look at the Java code created to get the zipCode string from nullable Address in nullable User:

public String getZipCode(User user) {
    if (user != null && user.getAddress() != null) {
        return user.getAddress().getZipCode();
    }
    return null;
}

And here’s the same thing in Groovy using the Safe Navigation Operator:

def getZipCode(User user) { user?.address?.zipCode }

Spock is the answer

And there is much more. One can easily define one’s own Domain Specific Language using Groovy. Meaning new keywords and expressions can be added into the existing language. In this way a test framework built on a base of JUnit was created. It uses a new and simple way to express test scenarios. This is Spock:

// standard Spock test
def '1 incremented by 1 should be 2'() {
    given:
    def a = 1

    when:
    a++

    then:
    a == 2
}

See? I was able to write the name of the test in a human readable sentence. Not usualJavaWayHardToReadEvenForDevs.

Spock is a BDD test framework - it focuses on a definition of behaviour. Behaviour-Driven Development tests should describe a scenario of application use case understandable not only by developers. We have a special vocabulary for such testing which testers, analyst or even stakeholders can read.

We prepare given structures as an input. This is the state of the world before actual testing begins. When contains the crucial event - the behaviour being executed for test purposes. Finally, the then section describes the expected state and all validations we want to pass. But with no verbose assertions, as you see.

Parameterized testing is great!

This article is just a brief introduction to the topic. We will cover real-life scenarios, mocking, BDD features, and Spock configuration in the follow-up. But before you go, let’s look at one painful topic of JUnit testing. I don’t like the cumbersome way of parameterized testing in JUnit. After all, there must be a reason that so few developers use it. But every Spock user I know uses parameterized testing. It’s so easy:

// parameterized test
def '#x plus #y should be #z'() {
    expect:
    x + y == z

    where:
    x  | y  | z
    -1 | 4  | 3
    11 | -5 | 6
    71 | 12 | 83
}

We have changed our BDD keywords. But it is still clear, right? Using parameters x, y and z we have defined 3 test scenarios in a compact way, having a pretty straightforward expect clause. Using placeholders such as #x in the name of our test we should see similar test report:

✔ #x plus #y should be #z

            ✔ -1 plus 4 should be 3

            ✔ 11 plus -5 should be 6

            ✔ 71 plus 12 should be 83

See you next time when we will go into more Spock features!

In the meantime, if you want to learn more about this topic, please check out our webinar.

Did you find this article useful? Share it on social media.

Need expert advice from our consultants?

Articles

CN Group

CN Group CZ a.s.
Prague Office 
Ve Smečkách 20 
110 00 Prague 1 
Czech Republic
Registration No.:
07885041

Locations
Prague
Contacts
Social Media
LinkedIn
Twitter
Xing
Facebook
YouTube
Instagram
Reviews on Clutch
clutch logo
© 2020-2022 CN Group CZ a.s., All rights reserved.
  • Sitemap
  • Legal Terms / Impressum
  • GDPR
  • Risk and Compliance