I watched the recording of the first #TDDLive webinar session yesterday. It was a really good conversation (nice to see a fishbowl format in action) and I’d recommend watching it if you get the chance. The part of the conversation about mocks was interesting as panellists were bringing up their experience of codebases (or people talking to them about codebases) that had loads of brittle tests because of their use of mocks. Due to this type of problem, the use of mocks has gained something of a reputation for being a bad technique and something to be avoided. In the session it was interesting to hear Nat Pryce talk about the origins of mocks in the context of creating state machines and wanting to confirm their outbound contracts. Personally, the main use I’ve made of mocks is as a placeholder for something I don’t want to create at this point in time so that I can reduce cognitive load, stay focused and concentrate on implementing the unit under test (or unit under design is probably more accurate). These are then like scaffolding that you can replace with the real implementation once you’ve got the mindshare and focus to move on. What interests me is that there must be a whole group of people out there who build test suites based on mocks, then realise that those test suites are brittle (in their context) and come up with the answer “mocks are bad”.
This took me back to the very early days of Enterprise JavaBeans when I was talking to someone about the different types of EJB and their remote interfaces. The person I was talking to was aghast about the idea of entity (data) EJBs having a remote interface because of the degree of chattiness this implied. I hadn’t really thought this through at the time (quite a common occurrence) as I thought that there must be a good reason for the remote entity interface to be there. However, stepping back and thinking about it, making remote calls from one layer of EJBs to another layer would obviously add a terrible overhead in terms of performance and complexity. I’m sure that it was useful in some scenarios but for most people it would be a poor design choice. However, in those early days of EJBs it would have been easy to just follow the docs unless you stepped back, looked at it and said “this can’t possibly be right”.
This came to mind yesterday because it feels like the people with those brittle codebases full of mocks should maybe have had a “this can’t possibly be right” moment. I suppose I’m in the privileged position of knowing a bunch of the people involved in coming up with mock objects so my initial reaction to them being a “bad thing” would be “this can’t possibly be right”. For me, this emphasises the importance of due diligence and going back to the source. If something doesn’t seem right then, to quote Gatiss and Moffatt’s Sherlock “do your research“. Rather than assuming that something is bad, go back to the original context for it being created and look at the writings of people closely connected with it (I’m sure there’s a book about this…). If your context is markedly different or the problem you’re trying to solve is dissimilar then why would you expect a tool or technique to give you good results. Any tool or technique is essentially a solution to a problem in a context (to coin a phrase) so try not to assume that it’s bad just based on your results or someone you saw on Twitter.
In many ways, this feels like just another variant on “select() isn’t broken”. If the thing isn’t working for you, put in the hard yards to make sure you’re using it as intended and putting in a good level of due diligence into the implementation (see also, TDD, pairing, mobbing, scrum, etc.)