An easier way to add Spock to an Eclipse/STS project

Normally I’m a big fan of Mr. Haki and his blog posts about Groovy. Recently, however, he wrote a blog post entitled Spocklight: Add Spock Support to Java Project in STS/Eclipse in which he accomplished his goal in what I find to be an overly complicated way. I’d like to suggest a much simpler alternative that uses Gradle.

(By the way, I’m sure Mr. Haki already knows this. He’s written about Gradle many times. Still, without using Gradle, adding Spock to an Eclipse project based on Maven is seriously tedious, as his post shows.)

I use SpringSource Tool Suite (STS) all the time, mostly because I’ve been an Eclipse user since version 1 and the Groovy and Grails plugins in STS are excellent. There’s no good Eclipse plugin for Gradle that I know of, but I’m comfortable running Gradle from the command line and having the results update my STS projects.

I started by creating a regular Groovy project in STS. I actually could have made it a Java project, but I decided to add Mr. Haki’s classes to my project before I ran Gradle and I wanted them to (mostly) compile. ¬†The only variation I use from regular Java projects is that I like to add a separate source folder for test classes. I also added the JUnit 4 library, since Spock tests descend from JUnit’s TestCase. Here’s my project layout, before I added Spock.

STS project layout before adding Spock

The User, UserService, and UserServiceImpl classes are written in Java and come from Mr. Haki’s example, which is available in his GitHub repository.

Now I need a Gradle build file, build.gradle. Here’s mine, which I reuse frequently. I’ll explain it after I show the file.

apply plugin:'groovy'
apply plugin:'eclipse'

repositories {
    mavenCentral()
}

sourceSets {
    main {
        java { srcDirs = [] }
        groovy { srcDir 'src' }
    }
    test {
        java { srcDirs = [] }
        groovy { srcDir 'tests' }
    }
}

def spockVersion = '0.4-groovy-1.7'

dependencies {
    groovy 'org.codehaus.groovy:groovy-all:1.7.5'
    testCompile 'junit:junit:4.8.1'
    testCompile "org.spockframework:spock-core:$spockVersion"
}

At the top, I added both the groovy plugin (of course) and the eclipse plugin, which is key here. After the plugins, I have a block called sourceSets, which changes the normal Maven project layout to match my Eclipse project layout. Probably the only notable part is that I always use the Groovy compiler exclusively for mixed Java/Groovy projects. The typical Maven separation of Groovy and Java code into separate source directories and then using javac for Java and groovyc for Groovy is problematic, IMHO. The groovyc compiler knows all about Java and handles cross-compilation issues just fine, thank you very much. Separating the code bases only leads to trouble.

In other words, my Gradle build maps all source code to the src directory and all tests to the tests directory, regardless of whether they’re written in Java or Groovy.

After that, I list my dependencies, which are Groovy 1.7.5, JUnit 4.8.1, and Spock 0.4 based on Groovy 1.7.

Now comes the fun part. The Eclipse plugin for Gradle adds two tasks that are useful here: cleanEclipse and eclipse. The former removes the existing settings from an Eclipse project, and the latter creates config files that will update the Eclipse project based on the dependencies listed in the Gradle build. I run Gradle like this:

c:\workspace\SpockTesting\> gradle cleanEclipse eclipse

That downloads the relevant jar files for all the dependencies (or, in my case adds links to them since I already have them locally). As long as Eclipse has the classpath variable GRADLE_CACHE set to my Gradle repository, all I need to do is refresh my project and I’m done.

STS project with SpockAnd there you have it. I can now right-click on the UserServiceImplSpec test and choose Run As -> JUnit Test and it works just fine:

STS JUnit testI can also run the normal Gradle build, which will run all the tasks and put the results in the build directory.

c:\workspace\SpockTesting\> gradle build

All the tasks run, and then if I open build/reports/tests/index.html in a browser view, I see the nice, hyperlinked display of the successful unit tests.

If you want my project, I checked it in at github.

My book Making Java Groovy is now available through the Manning Early Access Program.

%d bloggers like this: