Mock vs stub

A stub is a stand-in for a dependency that returns canned answers so the code under test can run; a mock is a stand-in that also records how it was called, so the test can assert that the code made the right calls with the right arguments. A stub supports the test and a mock is part of the verdict, and the difference decides what a failure means.

The longer version

Both replace a collaborator the test does not want to use for real: a payment gateway, a clock, a database, an email sender. A stub is configured with responses and does nothing else. The test calls the code, the code calls the stub, the stub returns the value it was given, and the test asserts on what the code produced. A mock is configured with expectations: called once, with this argument, after that one. When the code has run, the test verifies the expectations were met, and an unexpected call fails the test. The assertion has moved from the output to the interaction, which is why mocks are said to verify behaviour where stubs verify state.

The rest of the family is easy to place once those two are clear. A fake is a working but simplified implementation, an in-memory repository in place of the database. A spy is a stub that also records the calls it received for the test to inspect afterwards; it holds no expectations and fails nothing on its own. A dummy is passed to satisfy a signature and never used. Test double is the umbrella term for all of them. In everyday speech 'mock' covers the whole family, and most mocking libraries produce objects that behave as either, which is why the two words are so often swapped.

A mock ties the test to the implementation. A test that checks the repository was called with exactly these arguments in exactly this order fails when the code is refactored to make one call instead of two, although the result is identical, and it passes when the real repository would have thrown, because the mock never does. A suite of such tests describes how the code is written rather than what it does. A stub does its damage more quietly: a stub returning success for a gateway that in production returns a timeout means the timeout path is never run.

Common questions

What is the difference between a mock and a stub?

A stub returns canned answers so the code can run, and the test asserts on the code's output. A mock records how it was called, and the test asserts on those calls: that a method was invoked, how many times, with which arguments. A stub is scaffolding; a mock is one of the things being checked.

When should I use a mock instead of a stub?

When the interaction is the behaviour being tested: that an email was sent exactly once, that a payment was captured with the right amount, that a log entry was written on failure. Where the code's output already proves the behaviour, a stub is enough and a mock only ties the test to the current implementation.

What is the difference between a mock and a fake?

A fake is a real, simplified implementation, such as an in-memory database that actually stores and returns records, and the test uses it like the real thing. A mock has no behaviour of its own beyond the expectations the test configured. Fakes are preferred where they exist, because they behave consistently across many tests instead of being scripted per test.

What is a test double?

Test double is the umbrella term for any object that stands in for a real collaborator during a test: stubs, mocks, fakes, spies and dummies are all doubles. The word borrows from the stunt double, a replacement that is safe to use in situations the real one should not be put in, such as a payment gateway that must not charge a card during a unit test.

Can a mock and a stub be used in the same test?

A test commonly uses both: a stub for the clock or the configuration so the code can run, and a mock for the one collaborator whose call is the behaviour under test, such as the email sender. The rule is to mock only what the test asserts on and stub everything else, because every mock adds an expectation that a harmless refactor can break.

Bug reports that arrive ready to triage.

Collect replay, console, network and browser context with the Free plan.

<script src="…/widget.js" data-key="pb_pub_…">