Martin Fowler’s Mocks aren’t Stubs article presents a balanced comparison of two different styles of unit testing. According to Martin’s taxonomy I’m the type of chap who prefers “state-based” testing over “interaction-based” testing – that is, I prefer using stubs instead of mocks. And I increasingly encounter a downside of mocks that isn’t mentioned by Martin:
Suppose you’re working with legacy code. There are only a few tests; and the tests you already have are all large and complex, because the objects you’re testing were never designed with de-coupling in mind. You have to make a change to one or more of these objects, and you want to proceed test-first. The approach I’ve seen with increasing frequency (probably due to the easy availability of NMock) is to “mock out” a few of the closely-coupled objects. This allows the TDDer to get on with the work, but does nothing to alleviate the underlying problem of the smelly design.
Here, mocks are being misused, as “smart” stubs. I would much prefer to have seen the TDDer spend a little extra time refactoring the production code so that these tests – and all future tests – became easier and quicker to write. (The many excellent techniques in Mike Feathers’ Working Effectively with Legacy Code will help here.) So when I see mock objects being used as the easy way out of a tight corner, I seek instead to refactor away those nasty design smells.