By Jeff Langr and Tim Ottinger
Well, the title of this post is just wrong. The generic term for "things we use in testing to emulate production behavior" is test double, not mock. The casual programmer may bandy about the term mock when they mean test double, but it is technically incorrect and may lead to misinterpretation. We've never seen it make much of a difference to the end result of a programming conversation, but there are distinct definitions for the various implementations and uses of test doubles.
The term mock object stems from a 1999 paper by Tim Mackinnon, Steve Freeman, and Philip Craig, "Endo Testing: Unit Testing With Mock Objects." The authors' simple definition: "a substitute implementation to emulate or instrument other domain code." Mocks, or whatever you might call them in 2010, still serve the same purpose.
Use of mock objects in TDD circles grew dramatically over the next several years. Debate grew dramatically, too. The community debated about (a) whether or not to use them at all, (b) in what situations they were most appropriate, and (c) whether or not to use one of the mock tools that were starting to proliferate and pro-create.
In 2006, Gerard Meszaros published the book XUnit Patterns, which enshrined a handful of nuanced terms for the various kinds of test doubles. These terms had been shopped around in various agile forums for some time leading up to publication of the XUnit Patterns book. Today the taxonomy is commonly accepted by programmers and mock frameworks alike (oops, but "mock frameworks" itself is a misnomer, as these frameworks usually support all sorts of test doubles, not just mocks).
- Test Double is the generic term, the phylum for all our species of testing dopplegangers.
- Stub - An object that returns a specific, fixed value to the system under test (SUT). Stubs are usually constrained to a small subset of methods defined on a collaborating class. "When someone calls the
pricemethod, return the value 9.99."
- Fake - An object that completely emulates its production equivalent. The classic example of a fake is a lightweight, in-memory "database" object that allows for simple, fast emulation of a relational database interface.
- Mock - An object that self-verifies. A mock asserts that information sent to it is as expected. A test that uses a mock defines and verifies this expectation.
- Partial mock - An object that contains a mixture of production method implementations and mock method implementations. Partial mocks are generally used when you need to emulate non-existent behavior (i.e. abstract methods) or troublesome behavior defined on the same class you are testing, something that might indicate questionable design.
- Spy - An object that simply captures messages sent to it, so that the test can later verify that the SUT interacted correctly with its collaborator.
So, where do we stand on the debate? (a) Yes, use test doubles (b) when you must, (c) and use a tool if it makes things easier or clearer. Next time, we'll talk about more important things, such as what pitfalls to avoid when working with test doubles.