Skip to content
IRC-CodingIRC-Coding
Test DoublesStubMockFakeSpyUnit TestsMocking

Test Doubles Explained: Stubs, Mocks, Fakes & Spys

Master test doubles: stubs, mocks, fakes, and spys. Learn when to use each type with examples and best practices.

S

schutzgeist

1 min read
Test Doubles Explained: Stubs, Mocks, Fakes & Spys

Test Doubles: Stubs vs. Mocks vs. Fakes vs. Spies

This article covers the fundamentals of test doubles – including exam-style questions and key takeaways.

In a Nutshell

  • Stub: returns predefined answers
  • Mock: verifies interactions (expectations)
  • Fake: simplified, working implementation
  • Spy: records calls for later verification (combines stub + mock)

Core Definitions

Stub

Returns fixed answers without checking behavior. Useful for stateless tests where you just need predictable return values.

Mock

Verifies that specific methods are called with specific parameters. Essential when interactions between components matter.

Fake

A working but simplified implementation (like an in-memory database). Great for tests that need realistic behavior without external dependencies.

Spy

Records method calls and allows verification after the fact. Bridges stub and mock by supporting both preset returns and call tracking.

Key Points for Study

  • Stub: predefined answers, no behavior verification
  • Mock: define and verify expectations
  • Fake: functional simplification (e.g., in-memory repository)
  • Spy: record calls, verify later
  • When to use each: stubs for state, mocks for behavior, fakes for complexity
  • Common frameworks: Mockito, unittest.mock, Jest

Core Components

  1. Stub (answers)
  2. Mock (expectations)
  3. Fake (simplified implementation)
  4. Spy (recording)
  5. Test isolation
  6. Framework usage
  7. Setup/teardown
  8. Assertions
  9. Verification
  10. Maintenance

Practical Example (Discount Service)

// Stub
DiscountPolicy stub = new DiscountPolicyStub(10); // always 10%
int rabatt = service.berechneRabatt(kunde, artikel);

// Mock
DiscountPolicy mock = mock(DiscountPolicy.class);
when(mock.getRabatt(kunde)).thenReturn(10);
verify(mock).getRabatt(kunde);

// Fake
InMemoryDiscountRepository fake = new InMemoryDiscountRepository();
fake.add(new Discount(kunde, 10));

// Spy
DiscountPolicySpy spy = new DiscountPolicySpy();
service.berechneRabatt(kunde, artikel);
assertEquals(1, spy.getCallCount());

Common Exam Questions (Quick Answers)

  1. Difference between stub and mock? A stub returns answers; a mock verifies calls were made.
  2. When should you use a fake? When you need a functional simplification, like an in-memory database.
  3. What does a spy do? It records method calls and lets you verify them after execution.

Essential References

  1. https://martinfowler.com/articles/mocksArentStubs.html
  2. https://junit.org/junit5/docs/current/user-guide/
  3. https://testing.googleblog.com
Back to Blog
Share:

Related Posts