June 2008 Archives

Stone Soup

I’ve been to a lot of Ruby conferences this past year. Yet the more that I attend, the more that they seem the same. I see the same people giving the same presentations on the same topics. Sure, they add some content here, drop a slide there, or maybe add a different spin on the same subject as before. But, at the end of the conference, I find myself asking “What makes this conference different than any other conference?” There are more people? There are less people? It’s someplace different? That’s often all that I can say.

At RailsConf, Chad Fowler opened and offered one observation that I found particularly profound. He admitted that he doesn’t do particularly well in a classroom setting – and implied that conference talks are like a classroom environment.

That struck me to the core. That’s me.

At Ruby conferences, I see few people voting with their feet. However, I see many people who barely pay attention to the speaker. Instead, they are on IRC discussing how disappointed they are in the speaker, writing a Rails app or Ruby gem, or just surfing the net.

So why even go to the talks at conferences? Why have the talks? Obviously, most Ruby conference attendees would rather be doing something on their computer, social or otherwise.

Beteween games of Werewolf at Ruby East last year (my humble apologies to Charlie Nutter), Giles Bowkett and I were yakking away. Somewhat randomly, he says something like, “Man, you and I… we’re just scenesters.”

That’s exactly what I’d become. I didn’t realize it until that moment. That had never ever been me but it sure is now. And I bet that’s you too.

You go for the scenius.

That’s a Brian Eno-ism. It’s “the emergent genius of a colocated culture”. It’s that spark you get, that inspiration, that makes you feel smarter just because you’re working near and talking with the poeple that you are where you are.

I don’t see much exchange when there is a talking head, even a brilliant one, at the front of the room with an audience full of mostly silent people. Why is a group of such seemingly independently-minded people as the Ruby community willingly enslaving themselves to the words of one person after another for 45 minutes a pop? Just how educational does this really turn out to be?

“This town needs an enema” - The Joker, Batman (1990)

Why should Ruby conferences be traditional conferences? Just because everyone else does it that way? Odd. I don’t see this community (communities?) as followers.

Giles asserts that we’re a weird bunch of people. Hell, I thrive on it – just as much as I gag on the lack of weird when I return to my day job from a conference.

So why not just be weird instead of being like every other conference out there with their clearly delineated speakers, audiences, and Nascar-like corporate branding?

No I don’t mean Ruby Fringe (although I am going).

Let’s invert the process. More discussion. More hacking. Less talking heads.

Let’s make some awesome Stone Soup.

I’ve discussed this with some people around the community. The often conservative and stodgy DC Metropolitan Area may hold the first Ruby BarCamp. Does someone want to beat us to the punch? I triple-dog dare you.

Update 6/29/08: Bryan Liles pointed me at an article by Dave Winer about the “early days” of unconferences. His timing is serendipitous. Come on, people! Let’s make something happen!

Posted by evan on Jun 25, 2008

NoVaJUG presentation of Unit Testing J2EE from JRuby

This evening, I gave my first presentation of Unit Testing J2EE from JRuby to the Northern Virginia Java User’s Group. It was a very interesting experience. The audience asked some interesting questions – but it was also an insightful reminder of my origins as an engineer. Out of approxiately a 30 member audience, perhaps 4 had done any TDD and only a single one had ever used mock objects. While mocks have their origins largely in Java (at least their initial implementations), it is interesting to see that they have been far more readily adopted in the Ruby community than Java.

Also, Mocha suddenly jumped from v0.5.6 to v0.9?!

So jrsplenda broke when I tried to demo it on my wife’s spiffy new Macbook Air – as I was foolish enough to just ‘sudo gem install mocha’.

Who the hell has a public release at 0.5.6 and then another at 0.9? I am so integrating FlexMock into jrsplenda in the next release. I can’t see Jim Weirich doing anything like that.

I’m halfway tempted to redo and give my BDD with RSpec talk to NoVaJUG as a JRuby-Java BDD talk. More people should be doing BDD and not merely those of us working in dynamic languages. Were it so, I imagine that I would encounter far more testable and maintainable code in the Java community.

Slides from the presentation are available here

Posted by evan on Jun 24, 2008

Presenting at ERubycon in August

I’m extremely excited to announce that ERubycon has accepted my proposal to speak on JRuby testing of JEE. ERubycon is unique in that it is expressly focused on Ruby in the Enterprise. While “enterprise” is a squishy term to me (my take on it is “legacy/internal facing/business-to-business/large scale development”), I suspect that the constituency will be somewhat different than the other Ruby conferences that I’ve attended this past year (i.e., RailsConf, RubyConf, Ruby Hoedown, and Ruby East). As the majority of my work falls clearly into the enterprise space, I’m looking forward to ERubycon.

ERubycon is August 15-17 in Columbus, Ohio. I hope to see you there.

Posted by evan on Jun 02, 2008

Improving Java unit testing and introducing jrsplenda v0.1.1

Last week, I wrote about the pain of Java unit testing. At the end of it all, I said that I would supply some answers “tomorrow”.

One week and one RailsConf later, I’ll call this “tomorrow”.

In the previous article, I listed a handful of commons Java idioms that reduce testability. Three out of four of the issues may be rolled up into a higher level of abstraction: encapsulation kills. The remaining point may be summarized as Spring XML == code that most developers don’t test. Encapsulation prevents developers from injecting mock objects into their code. Without mocks, the unit under test lacks isolation. Without isolation, your unit test is an integration test at best and a massive FAIL at worse.

If you endured a Computer Science curriculum in college, I’m reasonably sure that the professor of your second or third CS class repeatedly hammered home: encapsulation is a key tenet of good object-oriented design. However, many dynamic languages only provide a brief nod, if any, to the encapsulation gods. For instance, Python does not support private or protected members. While Ruby does, it is trivial to route around those protections. What some may not realize is that, in this respect, Java is little different than Ruby.

Yes, that’s right. Java can be a bit on the promiscuous side of things too.

I’m not sure what you’re “java.policy” file allows in your Java installation but, on OS X, the default allows for Java reflection to route around field and method access privileges. Don’t believe me? Take a gander at the java.lang.reflect.AccessibleObject class that is the parent of Field, Method, and Constructor reflection objects.

With this, you could write/generate a lot of code to act as wrappers for Java objects to expose private, protected, and package scoped Fields, Methods, and Constructors. While this is somewhat interesting, we can do better.

So why bother using Spring for object creation and dependency injection? No, seriously, think about it. Do you test your Spring XML? I would bet every Java developer who reads this article that, as of the authoring date, that you don’t. Ruby is extremely testable. So why are you writing all of that glue code in XML and not testing it? Write it in a Turing Complete programming language and test it, for crying out loud!

But I digress (however only slightly)…

Ruby excels at DSL creation. This has been demonstrated with awesome effect in the unit testing/specifciation domain. But did you know that Ruby’s testing and specification DSLs (i.e., RSpec) can be used to test Java? Oh, yes, it’s true. And Ruby’s mocking libraries (i.e., Mocha, Flexmock, and RSpec mocking), with their ability to create mocks at runtime with just a line of code simply blow Java away.

So what if we put our chocolate in our peanut butter? JRuby, as of v1.1.2, provides workable Java integration such that a JRuby mock object, generated by Mocha, may be injected into a Java object instantiated in JRuby.

Next we write some java.lang.reflect calls, in JRuby (!!), to wrap each non-public field and method for a given Java object with a JRuby method. Yes, a JRuby method. The generated JRuby method takes advantage of the java.lang.reflect.AccessibleObject’s features to provide setters (JRuby already provides getters) for Fields and to provide direct access to Methods.

Now we can inject these JRuby-created mocks from Test::Unit or RSPec into almost any part (well, ok, except for final members and local variables) of our Java objects. Suddenly, we’re writing test code that’s a whole lot more readable and we’re writing a lot less of it!

Splenda

I call the field and method wrappers “Splenda” or “jrsplenda” for JRuby Splenda – to sweeten up Mocha. While there are still some minor limitations as of v0.1.1 (see the README provided in the github project), I’ve already re-written some of the JRuby RSpec from my current project to use Splenda. It works like a champ.

Working sample code has been supplied with jrsplenda in the github project. Nonetheless, it bears mentioning describing it in brief.

Splenda is made up of three helper modules: a MockHelper, FieldHelper, and MethodHelper.

MockHelper

The MockHelper, predictably, supplies mock objects but also provides a facility for generating a mock of a Java class and storing the mock in a member attr named after the Java class

Example

  # inside a spec or test....
  require 'rubygems'
  require 'jrsplenda'

  include JRSplenda::MockHelper

  splenda_mock_attr 'javax.ejb.SessionContext'

  # => Creates a @session_context containing a mock for a SessionContext in one line

FieldHelper

The FieldHelper wraps all non-public (and non-final) fields for a given Java object. This is awfully handy for injecting your mocks.

Example

  #inside a spec or test
  require 'rubygems'
  require 'jrsplenda'

  include JRSplenda::FieldHelper

  import 'my.fake.TestClass'

  t = TestClass.new
  wrap_java_fields t

  # => Generates setters for all non-public non-final fields of the TestClass instance pointed to by t

MethodHelper

The MethodHelper wraps all non-public methods for a given Java object. This one is nice for white box testing of internal methods.

Example

  #inside a spec or test
  require 'rubygems'
  require 'jrsplenda'

  include JRSplenda::MethodHelper

  import 'my.fake.TestClass'

  t = TestClass.new
  wrap_java_methods t

  # => Generates setters for all non-public non-final fields of the TestClass instance pointed to by t

Take away

  1. Java may work in isolation but it is better still with the assistance of a dynamic language
  2. JRuby, as of v1.1.2, can integrate well with Java
  3. JRuby + RSpec can test Java code
  4. Mocha + Splenda make this not only ridiculously easy but ridiculously readable
  5. Question whether you really need Spring. Dynamic languages running in the Java VM can accommodate your dependency injection needs; they’re far more testable than your Spring XML

The latest version is available on github. Clone the repository and ‘rake install_gem’ to get the gem.

Oh, and Splenda may cause diarhea and bloating. Just sayin’.

Update: Incidentally, Flexmock actually plays very nicely with JRuby. I’ll be adding support for it in Splenda in the next release.

Posted by evan on Jun 01, 2008