| name | test-doubles-strategy |
| description | Choosing between mocks, stubs, fakes, spies, and dummies based on testing needs. |
Test Doubles Strategy
Strategies for replacing real objects with test doubles.
Context
You are selecting the right test double for the job. Understand the tradeoffs of each approach.
Domain Context
- Stub: Returns canned answers; doesn't care how many times it's called
- Mock: Expects specific calls; verifies behavior
- Fake: Lightweight working implementation; slower but more realistic than stub
- Spy: Records calls; can verify and allow through to real object
- Dummy: Placeholder; passed but never used
Instructions
- Stub: Use when you need predictable return values; database returning test data
- Mock: Use when you need to verify that a dependency was called correctly
- Fake: Use for database or third-party service; test containers are modern fakes
- Spy: Use when you need both verification and real behavior
- Dummy: Use when dependency is required by signature but not used
- Avoid Over-Mocking: If everything is mocked, you're not testing integration
- Prefer Fakes: Modern practice uses test containers over mocks for external services
Anti-Patterns
- Mocking everything; you need at least some real code to test
- Over-specifying mocks; brittle tests that fail on implementation changes
- Mocking your own code; mock external dependencies, not your logic
- Complex mock setup that's harder than the test; use factories or test builders
- Never testing error paths through mocks; ensure your error handling actually works
Further Reading
- Martin Fowler, Test Double essay
- Gerard Meszaros, xUnit Test Patterns