Mocking and Test Doubles

Site Admin · 11 Sep 2026 · 8 views

Mocking and Test Doubles

Isolating the Unit Under Test

Units often depend on other things: a database, an email service, a clock, a third-party API. Testing against the real things is slow, flaky, and expensive. Test doubles are stand-ins that replace those dependencies with controllable substitutes, letting a unit test focus purely on the unit's own logic.

The Family of Doubles

  • Stub: returns canned answers to method calls.
  • Fake: a working lightweight implementation, such as an in-memory repository.
  • Mock: a double that records how it was called so the test can verify behavior.
  • Spy: wraps a real object and records calls for inspection.

The distinction matters less than the goal: replace the dependency, control its behavior, and verify the interaction.

Mocking with Mockito

import static org.mockito.Mockito.*;

@Test
void sendsWelcomeEmailToNewUser() {
    Mailer mailer = mock(Mailer.class);
    when(mailer.newId()).thenReturn(42);

    SignupService service = new SignupService(mailer);
    service.register("ada@example.com");

    verify(mailer).sendWelcome("ada@example.com");
}

mock creates the double, when...thenReturn controls the answer, and verify asserts that the mailer really received the expected call.

Verify Behavior, Not Implementation

Verify what the unit actually owes its collaborators: mocks shine for asserting interactions, like that an email was sent or a retry was scheduled. Do not assert incidental implementation details, such as the order of private helper calls, because those tests break on every innocent refactor.

Too Many Mocks Is a Smell

If a test mocks half the world, it is testing nothing but mocks. Prefer real data structures and simple fakes; reach for mocks mainly at slow and precious boundaries (network, disk, clock). The sweet spot isolates the unit with the least machinery that stays honest.

Key Points

  • Test doubles stand in for slow or external dependencies.
  • Stubs control answers; mocks record and verify interactions.
  • Mockito mocks with mock, controls with when, validates with verify.
  • Assert behavior the unit is responsible for, not incidental details.
  • Many mocks signal a design problem; prefer fakes for data-heavy code.
Share this post:

Comments (0)

Please login or register to comment.