Integration testing configuration validation with Spock in Spring-Boot

This is something I stumbled upon during my regular workday. We wanted to test-drive the validation of our externalized Spring-Boot configuration. It was obvious that we needed an integration test for this feature, since the Spring-Boot framework, as well as the file system, are heavy involved in this kind of test. But what condition did we want to check in order to determine if the test had successfully passed? We decided that our application should not start if misconfigured and as a consequence, we wanted the test to ensure, that the application hasn’t started.

Our first approached included using a regular Spring-Boot integration test, by using the @SpringApplicationConfiguration annotation. Sadly this route proved to be a blind alley, since Spock’s Spring integration tries to initialize the ApplicationContext prior to testing and this rightfully failed!

And so we had to run the test inside a regular unit test and manually initialize the Spring application inside the method. To be honest, I wasn’t really sure about how to initialize the ApplicationContext or how to feed the configuration into the test. Luckily we’ve stumbled about a very good official Spring-Boot sample project. Based on this code, we came up with an solution like the following.

This is the class backing the external configuration:

And this is a possible integration test:

As you can see, this is a normal Spock unit test (although it’s semantically still an integration test). The ApplicationContext is initialized as an AnnotationConfigApplicationContext and the EnvironmentTestUtils are used to inject an invalid external configuration into the ApplicationContext.

There might be other use cases in which one might like to manually initialize the ApplicationContext instead of relying on Spock to setup the integration test environment, so I thought this post could provide to be usefull for future generation of Spring-Boot hackers to come. You can find my complete sample project on GitHub.

Getting Groovy with Java and Spock


Nowadays I simply love testing and my work colleagues call me nicknames such as MC Test. But I haven’t always been this kind of a test zealot.
When I was introduced to Unit-Testing for the first time, back in university, I couldn’t wrap my head around it. Why test the code I just wrote? I just wrote the code, I knew it was working. And I verified that it was working by using a truck load full of print statements and checking field values inside the debugger!

It became even more mysterious once the concept of Test-Driven-Development was introduced. Writing tests before writing the code? This was even more insane!
And so I remember many years of writing production code without a single line of test code…or at least without a single line of useful test code, of course there was the sporadic Unit-Test for my getters and setters.

But the urge to follow good development practices kept on itching and I remember writing my first more or less useful Unit- and Integration-Tests for a Grails Web-Application using JUnit and Grails’ mocking and stubbing facilities (the difference between mocking and stubbing was completely unknown to me back then and my tests reflected this as well). And once the first bugs started to come ashore the TDD approach seemed to resonate with me. I started to adopt a technique I’ve coined Bug-Driven-Testing. Every time a bug was discovered I’d write a test that would evoke the buggy behaviour and so I could bugfix the code by developing against this new test.
It was at that point my testing spark was lit and not for long after this eye-opening experience, I discovered Spock mentioned inside the Grails docs. Since then I’ve used Spock almost exclusively for all my testing needs and while my test-fu matured, so did Spock (which is available as version 1.0 since 2015-03-02).

Testing Java production code with Spock

Although Spock is a Groovy testing framework it’s perfectly capable to test your Java code as well. In this post I’d like to give a small introduction into Spock.

Let’s assume we want to implement a small library that provides some String padding functions (this seems to be considered a really useful library inside the JavaScript community). As the build system I’d like to use Gradle. Normally I’d use Maven, since it still seems a bit more mature and sane, but since Groovy is a fist class citizen inside the Gradle ecosystem, setting up the project with Gradle is a tad bit easier (also the Gradle support in IntelliJ is getting more awesome with every release, while Maven is treated like a poor cousin).

The build.gradle file looks like this:

If you’re already familiar with Gradle this is self-explanatory. If not, just take this for granted now. This config simply pulls in all Spock dependencies and allows you to combine Java production and Groovy test code. Next we want to get going with our first test, TDD style. The tests are called Specification in Spock and your test classes normally have a *Spec.groovy suffix. Assuming we want to code a class called PadService, this is what our first test case in PadServiceSpec might look like:

In a glimpse you can identify this code as Groovy code, no semicolons, weee!
Spock follows a BDD-style test definition, mapping the arrange-act-assert test phases to given-when-then. Statements inside the then block are automatically evaluated as test conditions.

In order to make this test pass, we can write the simplest class possible like this (this time in Java):

But of course, this code will fail for every other parameter except the ones used in the Spock test. Now we could start adding additional tests, which will perform the same operations with different values. Or we could wrap our tests with a for-loop and initialize an array of different input and expected output values (please don’t!). Instead of having to do such cumbersome work, Spock provides a great solution for this use case, called Data Driven Testing. In my next blog post I’ll show how to use Data Driven Testing in order to test drive the PadService to a working version. The source code (the little bit that is already existing…) is available at GitHub.

So long, and happy hacking!