28 March 2007

jMock 2.0.0 RC1 released

We've released a Release Candidate for jMock 2.0.0, which includes our new syntax for specifying exceptions. There's a new look web site to go with it which describes the new features. Please take a look.

22 March 2007

Synaesthesia: Listening to Test Smells

We just gave our "Synaesthesia: Listening to the Tests" talk at QCon. The exercise helped us to clarify what we want to say about our ideas on Test-Driven Development.

For a more eye-churning version of the image, try Nat's blog.

In our experience, where we find that our tests are awkward to write, it's usually because the design of our target code can be improved. The trick is to let your tests drive your development—that's a hint as to why it's called Test-Driven Development. You can sensitize yourself to find the rough edges in your tests and use them for rapid feedback about what to do with the code. It's rather like Systems Thinking for code: I don't stop at the immediate problem (an ugly test) but look deeper for why I'm in this situation (weakness in the design) and address that†.

As Avi Naparstek once posted to the Test-Driven Development list, the flow for state- and interaction-based testing is different. With state-based testing, where objects are exercised in small clusters, I tend to clean up within the cluster when there's enough code to see what's happening; the design effort happens in bursts. With interaction-based testing, the design is more continuous. The tests are finer grain, so they're more active in shaping the code.

We'll be writing up some test "smells" and what they might mean on this blog.

With proper Systems Thinking, I should carry on a few more levels and think about how I ended up with a weak design in the first place, but that's for another day.

01 March 2007

"Stop Designing for Testability"

There's an interesting exchange going on in the .Net world (actually, in the Israeli .Net TDD with Mocks world, which I imagine is about as small as a community gets).

First, Roy Osherove wrote that it's occasionally worth breaking OO design principles to make code testable. Then Eli Lopian, supporter of TypeMock, responded by writing that this is a Bad Idea ™.

I'm with Osherove on this one. Although some of the rules he's worried about breaking derive from working with legacy languages, rather than one that really is object-oriented, he makes a fundamental point about Test Driven Development. The effort of adjusting your ideas to make them testable will give you better, more flexible code. This allows you to keep up with the changes that arise in any project and is the other half of the contract you sign when you choose incremental development. I'm sure that Lopian feels that his approach is the way to get there.

I'm not a fan of TypeMock, except where you're trying to crack open a legacy codebase. It's a very smart library but, to me, it misses the point of TDD with Mocks, which is to force the programmer to think about the relationships between the objects they're programming. When you override a feature in a class for the purposes of mocking (or, more often, stubbing), you're addressing a dependency between two objects, but you're leaving it implicit. When I come back to the production class, there's nothing there to tell me that it plays this particular role, so I'll have to do the analysis again. That's why I've never been keen on the cglib versions of the java mock libraries. If it's that simple an object and you don't want to introduce an interface, then don't mock, use the real thing.

But, if you have to mock out an object to get the test to work, then that object is an external dependency and should be passed in. Reaching in to an object and manipulating its internals ties the test to the implementation and makes it brittle—which is the usual objection made against interaction testing. In this case, I have to agree.

One more point, Lopian writes,

Have you ever tried to browse a code with loads of interfaces, it take ages because you have to keep finding the concrete implementation, and the place where the instance was created.
In my world that's not the case. First, the usual Java IDEs take me very quickly from interface to implementation. Second, in a codebase that uses Dependency Injection well, significant objects are instantiated in just a few places. The place where the instance is created usually turns out also to be where other objects relevant to my task are also created. Then I know that the design is working.

Correction. Oren Eini is the author of Rhino Mocks,

Free TestDox with JUnit4 and Eclipse 3.2.2

Inspired by TestDox I discovered a trick when using Eclipse 3.2.2 with JUnit4. If you lay out your test methods like this

When you fold the test class, it looks like this

If you've written your method names appropriately, the result is a compact description of the features of the class under test.