I got into a heated argument over testing practices at work the other day. That led me to think about the subject quite a bit, and have come up with a few laws of testing based on my experience:
- Only mock what’s needed to make the test deterministic and fast; otherwise call the real code
- A flaky test is worse than no test at all
- Good tests verify behaviour; bad tests verify an implementation
The worst thing about law number 3 is that it’s just stating the commonly known knowledge that coupling is bad and should de reduced, but for some reason some people don’t realise they’re increasing it when they write tests for the implementation.
Law number 1 needs some explaining. Mostly I’m only interested in mocking/stubbing/etc. functions that make a unit test no be “pure”. Usual suspects are file system operations, networking, databases, etc. I’ve seen a few examples that don’t fit the “traditional” examples but make good canditates. One that particularly opened my eyes was using a mock log object to state that error messages were logged when calling a function with certain arguments. Another situation is that in some embedded contexts it might be hard to even get a file to compile outside of a specialised environment. Mocking can make sense there too. Basically, whatever makes testing difficult should be mocked. Or to paraphrase Einstein, “All code should be mocked as little as possible, but not less”.
What are your testing laws? How do you disagree with mine?