At “XPDay London”:http://www.xpday.org, Tim Mackinnon and “Joe Walnes”:http://joe.truemesh.com/blog presented a “tutorial”:http://joe.truemesh.com/blog/000116.html on using Mock Objects to drive top-down design. With Nat Pryce and me, they make up a Gang of Four who’ve been reworking our thinking about Test Driven Development with Mock Objects.
“Martin Fowler”:http://www.martinfowler.com/bliki/ was there giving a keynote and came to the tutorial. We’ve been having an ongoing discussion with him about whether or not Mocks are a good idea. Martin’s view (I think) is that they expose too much about the implementation and so inhibit refactoring. Our view is that if you have control of your types and define appropriate interfaces, then those interfaces should be abstract enough not to get in the way — except now you should have a cleaner design.
Last week, while pairing with Peter Bell at work, I had both experiences. We reworked some code that only had a “cluster” ^(1)^ test and, true enough, it was easy to change the internals. On the other hand, we were trying to add more behaviour and the tests would have exploded if we’d coded up all the combinations. But the _really_ interesting event (to me, at least) was that a small code change (in formatting) required changes to all the tests because of the knock-on effects. When we went on to break up the Cluster tests into more orthogonal mock-based tests, it was much easier to get full coverage and a better design fell out.
So, my current conclusion is that Cluster tests can be easier to refactor, but that’s not the only flexibility that matters. What’s _most_ important, however, is to stick to the “Tell, don’t Ask”:http://pragmaticprogrammer.com/ppllc/papers/1998_05.html principle, which is the real key to flexible code.
^(1)^ Many TDD’ers like to work with small clusters of related objects, like a little integration test. They set some initial conditions and check the state of the objects at the end of the test.