Glossary
Mocking vs stubbing
Definition
Both replace a real dependency inside a test; a stub supplies prepared answers, while a mock also asserts how it was called.
A stub stands in for a dependency and returns whatever the test needs it to return. It holds no opinion about being used, and the assertion happens against the result the code under test produced. A mock is a stub with expectations attached: it records the calls it received, and the test then asserts on those calls, so what is being verified is the interaction rather than the outcome. The distinction is state verification against behaviour verification, and both belong to a wider family of test doubles that also includes dummies, fakes and spies.
Choosing between them is really choosing what you are willing to have break. A stub lets the implementation change freely for as long as the answer stays correct. A mock pins down the conversation between two objects, so a refactor that reorders calls or swaps a collaborator fails the test even though the observable behaviour is identical. Occasionally that is exactly the property you want. More often it is why a team ends up rewriting its suite alongside every change, until the tests are quietly abandoned as more expensive than the bugs they caught.
A rule that holds up in practice
- Stub the queries. Anything you call in order to get an answer should hand back a value and be checked through the result the code produces from it.
- Mock the commands, sparingly. Where the entire point is that a message left the system, such as an email dispatched or a payment captured, asserting on the call is the only way to observe it.
- Prefer a fake for anything stateful. An in-memory implementation of a repository usually reads better and breaks less often than a stack of expectations describing the same thing.
- Do not double what you do not own. Wrapping a third-party client and faking your own wrapper keeps every assumption about somebody else’s library in a single place.
Over-mocking produces a suite proving that your code calls the collaborators you wrote it to call, which restates the implementation rather than testing it.
Related
Contact
Have a project in mind?
Tell us what you are building — or what keeps breaking. You will get a considered reply from an engineer, not an autoresponder.