One of the coolest things I’ve ever seen in code. Ever.

I’ve been dabbling with Ruby, Groovy, and JRuby, for quite some time now. (Among other things, I’ve created Ruby and Groovy services for SonicESB.) I’ve never been a fan of Java as a language, but I’ve always thought it was a great platform. These dynamic languages take me back to the days when C and C++ allowed for great creativity and real power in software. I’m starting to feel excited about the ability to innovate in software, once again. Java is so tedious and restrictive in comparison. Great things have been done with it, but that’s mostly in spite of it, not because of it. And the complexity of all the frameworks is a result of the tight leash the language puts on you.

Not unlike Java, Groovy has not had the greatest smell to me, nor to Steve Yegge. I prefer the Ruby syntax, the Ruby style, and the Ruby community. (Yes, for me, why is a large part of the appeal of Ruby. The guy is brilliant.) Groovy is poorly documented, pretty dry, and seems like a bad derivative of Ruby. Just as Java is a dumbed-down C++, Groovy feels the same to me, with regards to Ruby.

However, I have to give kudos to Jeff Brown for doing a great job of showing Groovy in a great light last night. As much as I’ve read about and tinkered with Groovy, Jeff was able to demonstrate some very powerful constructs that I was not aware of. (Hence my poor documentation comment.)

One of the most amazing things I’ve ever seen done in software, something only a geek can appreciate, was Jeff’s demonstration of Groovy stubs. He set up the demonstration this way:

Suppose you have a class that checks for the existence of a file on the file system, and you need to isolate that test for a unit test. The problem with this class is that it was written such that you pass in a String, which is the full path and filename of the file, and the file’s existence is tested within the class under test. This is a problem for unit testing, because the Class Under Test (CUT) has a built-in dependency on the file system, and therefore, so does the test. You cannot test the class without setting up the filesystem to support the test. It’s complex, unwieldy, and not very portable.

As Jeff presented this problem, I couldn’t see how Groovy was going to be able to help. It seemed pretty insurmountable. I mean, the call to File.exists is sitting within the Java class. All you’re passing in is the String that identifies the file. As George Costanza would say, you’ve got no hand! How are you going to get hand?!

Well, I’ve already given the answer away: Groovy stubs. But, still, what does that mean, and how does it give you hand?

What you do is tell the stub how you want it to react to the method calls coming from the Java class under test. Still, you’re wondering, what does that accomplish? It’s not calling my stub for File.exists, it’s calling the File class for that!

What you do is wrap the invocation of the unchanged class under test in the stub, so that the stub can intercept the call to File.exists and respond the way you want it to, rather than the way it actually would if it were called. I don’t have the exact syntax (see, more documentation shortcomings), but it looks something like this:

// WARNING - pseudocode -- will not work
// create a stub for the class under test
def myStub = new StubFor(ProblemClass)
//define what you want the result to be
myStub.demand.exists { return true; }
//then call the method under test
myStub.use {
assert true == ProblemClass.updateFile()
}

When you run this test, the stub actually intercepts the call to File.exists and responds the way you told it to, without ever making the call to the File.exists method. File system dependency neutralized.

How often do you see software that acts that much like real magic? You’ve got to admit, that is beyond your expectations, really clean, and very cool.

Now, I realize that Groovy is making use of proxies, and that JRuby could certainly do the same thing. But you’ve got to give props to the Groovy team for something really slick and powerful.

More importantly, I found this to be an eye-opener, an exciting indication of what’s possible with these new dynamic languages. Whichever language you choose, a whole new world of power and creativity have made themselves available. I used to do very cool things with C function pointers and the C++ preprocessor. Now, I can see that there is once again the opportunity to work magic. The long, dark winter of Java is coming to an end.