Free — no signup required

Stubs vs. Mocks

2 min read

Stubs: Dumb Data Providers

A Stub is a fake implementation that returns pre-programmed responses to calls made during the test. It does not care how it was called, how many times it was called, or what arguments it received. It just hands over canned data so your code under test can continue executing.

  • Analogy: You are rehearsing a play. The actor playing the butler is absent. You tape a note to a chair that reads: "Dinner is served." The note doesn't act; it just provides the line when your character looks at it.
# A stub for a database client
class StubUserRepository:
    def find_by_id(self, user_id):
        # Always returns the same canned user, regardless of user_id
        return {"id": user_id, "email": "[email protected]", "name": "Test User"}

Mocks: Behavior Verifiers

A Mock is smarter. It is used to verify interactions — that your code called another component in the expected way. You use mocks when the act of calling something is itself the behavior you want to test.

  • Analogy: You are rehearsing the play. The actor playing the butler is absent. You bring in a substitute and brief them: "At the end of this scene, I need you to confirm that I made eye contact with you and said 'Thank you, Jeeves' exactly one time, with the correct tone."
from unittest.mock import MagicMock

def test_send_welcome_email_calls_email_service():
    # Arrange
    mock_email_service = MagicMock()
    stub_user_repo = StubUserRepository()

    service = WelcomeService(user_repo=stub_user_repo, email_service=mock_email_service)

    # Act
    service.send_welcome_email(user_id=55)

    # Assert — this is what makes it a Mock: verifying the interaction
    mock_email_service.send.assert_called_once_with(
        to="[email protected]",
        subject="Welcome!"
    )

The Golden Rule

The distinction comes down to what you are asserting on:

  • Stub: You assert on the return value or state of the system under test. The fake just provides data.
  • Mock: You assert on the interaction — was a method called? How many times? With what arguments?

If you are checking what your function returned, use a Stub.
If you are checking that your function called something correctly, use a Mock.

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free