The agony of Java unit testing

Java unit testing *sucks*!!!

There, I said it.

Come on, it does. I know, 8 years ago, JUnit was the bees knees. But let’s face it: when you’re working on a project, you’re behind schedule for whatever reason, and you have a deadline looming, where’s the first place that you cut corners?

Unit tests. Always.

Why?

  1. Lack of perceived value of testing (in other words: I see the happy path works so what’s your big problem?)
  2. No one is going to ever touch this code again after this release
  3. Java is just difficult to test

Let’s talk about these….

Why You Don’t Test (a.k.a., why you’re brain damaged)

Lack of perceived value of testing

If that’s the way you feel, then you shouldn’t ever call yourself an engineer. You’re just a hack. Still, I’ll assume that there’s hope for you yet because you’re reading this article in the first place.

The “Somebody Else’s Problem” Field

You’re leaving the project soon. Or you honestly believe that your shit doesn’t stink. Or you’re just going to leave it for the next guy. It’s somebody else’s problem. There’s one response to this: in this business, frequently, that somebody is you. If you can’t maintain your own code then you’ve just shot yourself in the foot. Congratulations.

But, now, to the heart of the matter.

Java is just difficult to test Now I know that I’m not the first one to say this. However, in my opinion, what makes difficult to test are the idioms and practices that developers have acquired over the 13 years that Java has been around. Many of these idioms and practices fly almost completely counter to testing – for in order to be able to test effectively, we must be able to isolate the unit under test. How do we do this in Java? Dependency injection. Come on, you knew I was going to say that, right?

Evil/Brain-Damaged/Detrimental Idioms/Practices

  • Enterprise Java Beans. Come on, already. Private variables mutated by the container based on an XML deployment descriptor (so we’re coding in XML now )? Are you testing your deployment descriptor? You probably should be. Have I ever done it. Not yet….
  • Spring. Yes, POJOs are good. Actually, I’ll amend that. POJOs are fucking awesome – especially when every member variable is exposed via a getter and a setter. Unfortunately, you’re now effectively writing code in XML. So are you going to write tests just to exercise your XML? If you aren’t, you should be. That XML creates and links objects together. As soon as you start coupling things dynamically, you have a relationship that could break and therefore warrants testing.
  • private/protected member variables. We need these, don’t we? Sometimes, yes, actually, we do. However, if they aren’t wrapped (see Spring above) then Houston we have a problem.
  • static final used for non-primtive/String constants. This is simply everywhere in the Java universe: developers statically initializing constants with Objects. This is awful. Why, you ask? Because how the hell are you ever going to be able to inject a value for that static final Object? It’s assigned at classloading time. So, basically, grab your ankles and BOHICA.

Unfortunately…

  • Some of these hurtful practices are necessary
    • Encapsulation
    • Spring XML (if you’re stuck coding Java in the first place)
  • Sometimes we’re working in legacy code
    • Limited ability to change existing code; stuck with bad practices
    • Existing unit tests are sometimes lacking

How do we get better?

Come back tomorrow. We’ll talk. Seriously.

Posted by evan on Sunday, May 25, 2008

blog comments powered by Disqus