Glossary
Mock vs Stub vs Fake
All three are stand-ins for a real dependency in a test. A stub returns canned answers. A mock also records and verifies how it was called. A fake is a lightweight but working implementation.
These get used as synonyms, but each does something distinct, and picking the right one keeps tests focused on what they're actually checking.
Stub — returns a fixed, canned response regardless of input. Used to control what a dependency "says" so you can test how your code reacts. getUser() always returns a specific test user, no matter what ID is passed.
Mock — like a stub, but it also records how it was called and lets the test assert on that. "Was sendEmail() called exactly once, with this address?" That's a mock doing double duty as both a stand-in and a check.
Fake — a real, working implementation, just a lightweight one. An in-memory database instead of a real one; it behaves correctly, just without the production infrastructure.
Why it matters
Overusing mocks turns a test into a check of "did my code call these exact functions" rather than "does my code produce the right result" — brittle, and it breaks on refactors that don't change behaviour. Fakes are usually the better default when a real dependency is too slow or unavailable to use directly, because they preserve real behaviour.
In practice
This distinction matters most at the unit and integration layers — see unit vs integration vs end-to-end testing. It doesn't apply to autonomous testing, which drives your actual running app rather than substituting for any part of it.
See also
See how this plays out in practice — start a free run or read the autonomous testing guide.