Mock Objects – Quick Follow-Up

Following up on my post from yesterday I re-read the revised version of Fowler’s Mocks Aren’t Stubs article. With the whole article being a good read, this is the part that I consider the most important to me:

It’s at this point that I should stress that whichever style of test you use, you must combine it with coarser grained acceptance tests that operate across the system as a whole. I’ve often come across projects which were late in using acceptance tests and regretted it.

Most projects I worked on, most teams I worked with, did some kind of testing. None TDD. None came even close to what the grand masters are doing in this area. But we all tried our best.

However, what most of us never realized is that unit testing is really just that. *Unit* testing. I remember when back in 2003 (plus minus a year) I worked on a Java (Micro Edition) navigation software and I wrote tests (which I called “system tests” back then) for running the whole app in a ‘headless’ emulator and logging all navigational actions. The test then compared this to the expected output. Running time was up to a minute for some of these tests. In another corner of this project I wrote “graphical tests” which rendered the 2D and 3D view of the navigation system and compared the images to the expected output. After I left the project, the colleagues quickly dropped most of the tests. (In fact, most of the unit tests were dropped, too. They considered them a burden. But that, I guess, is a different story.) I, however, knew how helpful these tests were. More than once did I make a simple change in an ‘unrelated’ class and it would magically affect the output of the ‘advisor’ component – not drawing the correct direction sign anymore. The tests didn’t necessarily help me to spot the source of the bug. But they made sure I did not commit breaking changes.

On a more recent project, a proxy server written in Ruby, I applied three levels of “system tests”: I used “spike tests” to drive a set of objects from all layers, but with a SQLite3 database instead of the real thing. Then I added “black box tests” running the system as a whole and hitting it with certain HTTP requests. Still using the SQLite3 database setup and running the tests on the local developer machine or the build server. Plus I added “deployment tests”. More or less the “black box tests”, but running against the deployed system. Because the proxy was the place where I had to add quick changes (because the proxied system was to hard to change), these tests allowed me to move very quickly from changes to deployment (to the test system) and on to production.

To make this long story short: Two things are important for me. 1. I am all with Uncle Bob in that you should always consider the database just an implementation detail. Make sure from the very beginning that you can replace it with an in-memory or SQLIte3 database. Or flat file. Or fake. Or whatever. 2. Use fine-grained unit tests. Plus, use coarse-grained acceptance tests. (What I called “system tests” or “spike tests” above.)

I’ll continue reading up on mocking and testing etc.. I feel I have a lot more catching up to do.. :/

tfdj

Donald Knuth

Well, what can I say.. I got distracted by this rather interesting interview with Donald Knuth.

It reminds me of my early years at the university. I feel like I can share Knuth’s point of view on many topics. Like Extreme Programming, Parallel Programming and “everything else”. But I also understand the thrive for new approaches like Extreme Programming and everything related to multi-cores and parallelism. It’s fair to say that I have two hearts beating in my chest.

My early years at the university I learned the old ways. Older professors. Older ideas. Still relevant! Make no mistake there.. But after a few years I noticed a shift. The professors noticed it, too, I guess. And most adapted successfully. I (we all, I guess) went through the Unified Process and the Personal Software Process to Extreme Programming and beyond.

I’ve spent six and a half – mostly good – years at the University of Karlsruhe. Blessed with professors like Tichy and Goos and some more who’s names I don’t recall correctly right now..

Amen,
tfdj

Mock Objects

I missed Uncle Bob’s article about “Manual Mocking: Resisting the Invasion of Dots and Parentheses” and only found it through this blog post: “Think different about mock objects!”

Good stuff.

To be honest I feel like I did not keep up enough with all the Mocking and TDDing stuff in the last few years. A few days ago I started a new pet project to help me catch up a little bit. Let’s see how this turns out..

Anyway, the XPlayer blog post has some valuable (for me!) points:

One thing I learn is that mock objects are a design tool, while many people see it only as a technique for speeding up unit tests.

Because you should use mock objects as far as you can apply TDD, whereas you can design and *discover* interfaces (and roles), and assign responsibility. On the other hand, in front of a third-party library you cannot follow this process, since the code is not under your control, and you cannot modify it.

Because if you use mock objects with third-party libraries (two concrete examples taken from our recent projects: isolating our tests from the database in a Rails app, or in a java app using Hibernate ORM), you’ll write tests that *guess* the library behaviour, and your guesses may be far away from the actual behaviour.

So, I’ll repeat myself, following this “mocks as a design tool” approach, you’ll mock only types you own.

I basically quoted the whole post here.. :) Go on, read it!

I’m off to read the original Uncle Bob post now..

Cheers,
tfdj