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.

What is “Making Java Groovy”, anyway?

This week, the first two chapters of my book Making Java Groovy became available through the Manning Early Access Program (MEAP). I thought I’d explain a bit more about the purpose of the book here, while potential readers still have a chance to affect it.

Also, this post is an attempt to answer the question, “Making Java Groovy? WT(Heck) is that all about? Is that supposed to be funny?”

Uh, sort of. The title is a bit of a pun, though I’m not sure how well it translates to non-native English speakers. The idea behind the book is that Groovy is not intended to replace Java, but rather to enhance it wherever it helps the most. This book is about Java and Groovy integration. Java books talk about Java. Groovy books talk about Groovy. This book is about blending them together in productive ways. So yeah, the attempt at humor is kind of lame, but it does have a purpose.

Besides, when all the reviewers recoil in horror at the name, I’ll probably change it again. This book has been through at least two other name changes already, but more about that in a later post.

I’m assuming that most of my target audience has been using Java for years, or at least has a codebase of Java to manage or maintain, so they’re not in a position to throw everything out and start over. The good news is that with Groovy you don’t have to. Groovy has always been about making Java better, rather than replacing it.

Let me just give you the real theme now:

Java is good for tools, libraries, and infrastructure. Groovy is good for everything else.

For example, if you’re a Java developer working on a web application and you can choose to use Grails, wonderful, more power to you. If you are using Spring MVC, or Spring Web Flow, or Spring Roo, or Tapestry, or Wicket, or (sigh) JSF, or Seam, or Struts 2, or (whoa) Struts 1, or even (shudder) raw servlets and JSP’s, hey, no problem. You can still add Groovy in ways that will make your life easier.

That’s the bottom line. With Groovy, you don’t have to lose anything, and you gain a great deal. I know I have. I use Groovy all the time, and I rarely use it alone. I hope, through this book, to show you ways you can use it too, without having to throw anything away and start over.

Follow

Get every new post delivered to your Inbox.

Join 1,374 other followers

%d bloggers like this: