Testing with Grails

Marisniulkis
Survata Engineering Blog
9 min readFeb 4, 2020

What are we looking for in our tests?

Ken Beck’s article Test Desiderata provides a good starting point for thinking about what makes a good test. In the article, Ken explores the 10 properties tests should have. I personally think “inspiring” is the most curious one, but it makes sense — passing tests should inspire confidence!

Go and read the article before continuing.

I’ll wait right here.

[2 minutes later]

Ok, glad you made it back. Here we go.

Grails is a Groovy-based web application framework for the JVM built on top of Spring Boot. It’s aimed at writing applications quickly and productively. Survata uses Grails as the backbone of our application API that we use internally and that we expose to partners. While building applications with Grails is relatively easy, scaling and testing them brings its own set of challenges.

In this guide, I’d be focusing on exploring the types of artifacts that make up a Grails web application and recommending how to test each artifact. Buckle up!

Grails basics

Grails is a convention over configuration framework for web development. It has a predefined folder structure that determines how the framework interprets and wires together features. Three fundamental types of artifacts reside in an application: domains, which map to DB schema tables; services, where business logic should live; and controllers, the web layer of your application. Each layer requires its own approach to testing, you should keep in mind what your goals are when you are writing tests for each type of artifact.

The basics of Grails testing

Grails leverages Spock as a testing framework. Spock is a testing and specification framework for Java and Groovy. It includes unit testing, integration testing, mocking and stubbing.

To run tests grails, navigate to your project in a command line and run grails test-app.

For all the examples below we use Grails version 3.3.9.

Structure of a Spock Test

Test in Grails resides under src/test and src/integration-test. Because this is a convention, Grails will find and run everything that is a test under those folders when the command grails test-app is run.

Spock specification and features

Tests are recognized by Spock if a Groovy or Java class extends the abstract class Specification.

What are we looking for in our tests?

Ken Beck’s article Test Desiderata provides a good starting point for thinking about what makes a good test. In the article, Ken explores the 10 properties tests should have. I personally think “inspiring” is the most curious one, but it makes sense — passing tests should inspire confidence!

Go and read the article before continuing.

I’ll wait right here.

[2 minutes later]

Ok, glad you made it back. Here we go.

Grails is a Groovy-based web application framework for the JVM built on top of Spring Boot. It’s aimed at writing applications quickly and productively. Survata uses Grails as the backbone of our application API that we use internally and that we expose to partners. While building applications with Grails is relatively easy, scaling and testing them brings its own set of challenges.

In this guide, I’d be focusing on exploring the types of artifacts that make up a Grails web application and recommending how to test each artifact. Buckle up!

Grails basics

Grails is a convention over configuration framework for web development. It has a predefined folder structure that determines how the framework interprets and wires together features. Three fundamental types of artifacts reside in an application: domains, which map to DB schema tables; services, where business logic should live; and controllers, the web layer of your application. Each layer requires its own approach to testing, you should keep in mind what your goals are when you are writing tests for each type of artifact.

The basics of Grails testing

Grails leverages Spock as a testing framework. Spock is a testing and specification framework for Java and Groovy. It includes unit testing, integration testing, mocking and stubbing.

To run tests grails, navigate to your project in a command line and run grails test-app.

For all the examples below we use Grails version 3.3.9.

Structure of a Spock Test

Test in Grails resides under src/test and src/integration-test. Because this is a convention, Grails will find and run everything that is a test under those folders when the command grails test-app is run.

Spock specification and features

Tests are recognized by Spock if a Groovy or Java class extends the abstract class Specification.

What are we looking for in our tests?

Ken Beck’s article Test Desiderata provides a good starting point for thinking about what makes a good test. In the article, Ken explores the 10 properties tests should have. I personally think “inspiring” is the most curious one, but it makes sense — passing tests should inspire confidence!

Go and read the article before continuing.

I’ll wait right here.

[2 minutes later]

Ok, glad you made it back. Here we go.

Grails is a Groovy-based web application framework for the JVM built on top of Spring Boot. It’s aimed at writing applications quickly and productively. Survata uses Grails as the backbone of our application API that we use internally and that we expose to partners. While building applications with Grails is relatively easy, scaling and testing them brings its own set of challenges.

In this guide, I’d be focusing on exploring the types of artifacts that make up a Grails web application and recommending how to test each artifact. Buckle up!

Grails basics

Grails is a convention over configuration framework for web development. It has a predefined folder structure that determines how the framework interprets and wires together features. Three fundamental types of artifacts reside in an application: domains, which map to DB schema tables; services, where business logic should live; and controllers, the web layer of your application. Each layer requires its own approach to testing, you should keep in mind what your goals are when you are writing tests for each type of artifact.

The basics of Grails testing

Grails leverages Spock as a testing framework. Spock is a testing and specification framework for Java and Groovy. It includes unit testing, integration testing, mocking and stubbing.

To run tests grails, navigate to your project in a command line and run grails test-app.

For all the examples below we use Grails version 3.3.9.

Structure of a Spock Test

Test in Grails resides under src/test and src/integration-test. Because this is a convention, Grails will find and run everything that is a test under those folders when the command grails test-app is run.

Spock specification and features

Tests are recognized by Spock if a Groovy or Java class extends the abstract class Specification.

Specification contains a number of useful methods for writing specifications. Furthermore, it instructs JUnit to run your specification with Sputnik, Spock’s JUnit runner. Thanks to Sputnik, Spock specifications can be run by most modern Java IDEs and build tools.

Spock lets you write specifications that describe expected features (properties, aspects) exhibited by a system of interest. The system of interest could be anything between a single class and a whole application, and is also called the “system under specification” or SUS.

Fields

Instance fields are a good place to store objects belonging to a specification’s fixture. It is good practice to initialize these fields right at the point of declaration. (Semantically, this is equivalent to initializing them at the very beginning of the setup() method). Objects stored into instance fields are not shared between feature methods. Instead, every feature method gets its own object. This helps to isolate feature methods from each other, which is often a desirable goal.

Sometimes you need to share an object between feature methods. For example, the object might be very expensive to create, or you might want your feature methods to interact with each other. To achieve this, declare a @Shared field.

Fixture methods

Fixture methods are responsible for setting up and cleaning up the environment in which feature methods are run. All fixture methods are optional.

Feature methods

Feature methods are the heart of a specification and are Spock’s way of calling a test method. By convention, feature methods are named with String literals. These are the names that we see when the test suite is running so it’s important to use meaningful names that convey the purpose of the test.

A feature method is structured into so-called blocks. Blocks start with a label and extend to the beginning of the next block or the end of the method. There are six kinds of blocks: given, when, then, expect, cleanup, and where blocks.

Image source: Spock reference documentation

But talk is cheap…

Alright, alright, I have been talking a lot without showing you how it is done. Allow me.

Let’s say we have an application that manages campaigns for its customers and we have a Campaign domain object and a CampaignService class to manage the logic of creating, updating, listing and deleting campaign objects. While we build the operations of CampaignService we also update our tests.

Testing domain classes

Let’s look at a unit test for the Campaign domain class.

This is a good example of using the traits that Grails provide for testing, but be mindful to avoid testing every feature of the framework. Test your assumptions of the behavior and dependencies your domain classes should have.

Each block in the feature method is providing information to the following block and the order of execution is as shown. This test is checking a basic campaign creation flow.

Grails provides on top of Spock a few utility classes and interfaces to test the different artifacts it provides.DomainUnitTest, ServiceUnitTest, and ControllerUnitTest are Groovy traits provided by Grails for unit testing domains, services, and controllers respectively. You can use them or not, the traits provide the convenience of having a keyword domain, service and controller respectively to refer to an instance of the class under test and provide a mock registering in the application context (Autowired for you). Each of the traits provides specific utilities e.g ControllerUnitTest provides access to variables view, request, response and model in addition to wiring controller to the given controller being parametrized. I recommend since you are already riding this horse that you take advantage of it and use it for your unit tests. We use it extensively for controllers and domain class tests.

Testing Services

You can unit test services in a similar way you test domain classes by extending ServiceUnitTest. For most of the operations we do at Survata, we instead prefer to integrate test our services (since our services handle pretty much all our web application logic.)

Here is an integration test for our CampaignService class (as denoted by the annotations at the beginning of the class).

Testing controllers

At the beginning (We are getting rid of this pattern) our controllers looked like:

Now we are moving to a more all logic in services pattern and our controllers look more like:

More beautiful huh? And easier to test as well. Also, note we moved to use JSON views instead of rendering as JSON.

Now to test this controller function we can mock the service and get a result and test the true work of the controller, the model, and the view:

Simplifying our controllers also simplifies our tests and how we approach them.

What about integration tests for controllers? This is an approach:

Note: you’ll need to include this library for using RestBuilder

Gradle config: testCompile “org.grails:grails-datastore-rest-client”

There are so many more options in terms of testing your controllers’ results, but that is subject for another guide (about contract testing APIs).

Testing exception conditions

All of the code examples so far are simple and happy, nothing bad happens in them. But that’s usually not the case in our test so let’s look at an example on how to test when Exceptional cases occur.

Spock is very powerful and there are many more features worth examining that we use like data-driven testing with data tables and Interactions.

Extra tips

Groovy metaclass

You can take advantage of the Groovy metaclass system to mock results. For example:

When the searchText function is called for a user object in your test, then a user with username Mari will be returned.

IDE support

You can run tests on the command line using Grails-provided commands or use your IDE support for Grails to run them. There is a guide on how to run tests for IntelliJ that’s useful if you use IntelliJ. TL;DR: Remember to run the test as a Grails test as opposed to JUnit tests if you are using Grails specific features, which is our case most of the time. This is a free tip brought to you by the pain of seeing my tests fail in IntelliJ when running as JUnit tests. (You’re welcome!)

Wrapping up

This was supposed to be a haiku and ended up being an essay. That’s because there’s a lot of ground to cover, but fear not, once you understand the basics and get some examples, it all becomes clearer.

May your tests always inspire (confidence).

You want to know more you say? I hear you, here is another useful link:

Grails latest testing guide

--

--

Marisniulkis
Survata Engineering Blog

Engineer, sometimes poet. Diversity advocate. VenusIT and VoiceFirst Weekly founder.