Making a mockery of mocking
Unit testing and TDD are all the rage. This is a good thing! Not long ago, most conversations I had about testing turned into a battle of philosophy about whether testing should happen.
Nowadays, it seems that battle has been largely won. But as soon as you solve the big problem, the smaller problems start to show up. And that brings me to today’s “small problem”: The mockery that is “mocking”.
I’m not going to tell you not to use mocks, although there is a strong case to be made, and I may weigh in on that later.
Today I’m only concerned with the confusion surrounding the term itself. I see this all the time on StackOverflow, with questions like:
“How do I mock this function?” or “How do I mock this object?”
These are (usually) confused questions. They are (usually) asked by people who are under the false impression that any sort of stand-in implementation used during testing is a mock. This is, well, a mockery!
A better term for this use of the word “mock” is simply “test double.” A test double “is a generic term for any case where you replace a production object for testing purposes,” according to Martin Fowler, who goes on to explain several common types of test doubles:
- Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
- Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an InMemoryTestDatabase is a good example).
- Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what’s programmed in for the test.
- Spies are stubs that also record some information based on how they were called. One form of this might be an email service that records how many messages it was sent.
- Mocks are pre-programmed with expectations which form a specification of the calls they are expected to receive. They can throw an exception if they receive a call they don’t expect and are checked during verification to ensure they got all the calls they were expecting.