I found an article that preaches a technique that I’ve recently adopted. That technique, I guess, can be formerly referred to as design by contract. (Keep this page bookmarked because I’m thinking of posting a brief example over this weekend.) In short, what I do is start my unit tests using abstract classes. Abstract classes?? Get the Hell outta here, right? Those went out of style with high-top Pro-Keds didn’t they? Well as it turns out there are a few good uses for them, one being unit testing. How does it work? I’m glad you asked! Let me explain…
Abstract Test Driven Development
When I begin a unit test I start with the word “abstract” (actually I start with the word package, followed by a package name followed by several import statements but since I use an IDE I don’t write that part so I start with “abstract” as I was saying…) And I include an abstract method, “getInstance”. I then make “getInstance” return some named type that doesn’t exist. That’s the fun part because I can be as clever as I want and even change the name half into my design without hassle. I then pound out all of my test (*ahem* spec) code into these neat little method bodies that are free from the clutter of implementation details. That’s where it becomes even more fun because I can be as creative as I want defining the behavior of my test object, changing names as I need without trouble. The test methods focus on how the object is used and they actually write the interface for me. When I’m done, IntelliJ Idea fills my screen with all of these little red squiggly lines under each undefined type and reference and I merrily go through with my F2 key and correct each one. (F2 steps between file errors, Alt+Enter fixes each error generating interfaces and methods with simple key strokes. You gotta try this, it’s loads of fun!) I stub out my interface, then (using Ctrl+Shift+Backspace) I quickly return to my test and resolve each undefined method or reference. What I’m left with is an abstract class and an interface which together do nothing but in reality do everything. They define the contract. The test writes the contract. The interface is the contract.
The next step is to place my cursor on the test class name and hit Alt+Enter. (In Eclipse you substitute Ctrl+1 for Alt+Enter and get the same magic.) What does my editor ask me? “Hello Cliff, my it’s a sunny day today! Would you like me to generate an implementation of your beautiful abstract unit test case for you? By the way I’ve also noticed that your chair is slightly unleveled. Would you care if I adjusted that fold of rug tucked underneath the wheel?” So my actual test case is written for me while my seating is adjusted. (Man, I love Idea! Eclipse, unfortunately doesn’t have the seat leveling plug-in yet.) I am then placed inside my actual unit test at the point where I am supposed to dream up a clever name for the actual object that I’m going to test. I haven’t created it yet so, once again, I can be as imaginative as I need to be. I prefix my object name with “new ” and suffix it with parenthesis “()” which may or may not include its dreamed up dependencies. My editor is smart enough to understand that I want to create the tested object at this point so it generates the concrete walks me through. (The constructor and any additional interfaces methods can be generated by chasing the light bulb and using Alt+Enter.) I return in a flash to my last place of editing. (I was working in the concrete unit test before I started writing the concrete implementation. I use the same Ctrl+Shift+Backspace to walk back there.) I tell my editor to run my unit test (in Idea a right click on the test class name will add an option to run the unit test to your context menu. Idea is also smart enough to run the compiler over everything first.) an wait for my red bar.
We love the red bar don’t we?
Here’s an important detail that is often overlooked by many when practicing TDD. The red bar is just as important as the green bar because sometimes a test can pass before you’ve written a line of implementation logic. Initially a green bar usually means your unit test is either broken or unnecessary. After the red bar I play fill-in-the-implementation-blanks using Ctrl+Alt+B to step into the implementation of a method from the calls in my base test case. It feels and looks much better than it sounds so I’ll come back later with an actual example so you can see what I’ve been yapping about in my other article.