Excessive Mocking (Mockery)
Excessive mocking replaces nearly all collaborators with mocks, so tests verify interactions instead of behavior and pass even when the system is broken. Mock only true boundaries, prefer sociable tests and fakes, and add contract tests.
Excessive mocking, sometimes called mockery, is the practice of replacing almost every dependency with a mock object. The tests end up verifying that specific methods were called in a specific way rather than that the code produces correct results.
Why It Happens
Mocks make units trivially isolatable, and isolation is held up as the ideal of unit testing. When code has many dependencies, mocking them all is the path of least resistance. Some teams treat any real collaborator in a test as forbidden, pushing toward mocking even simple value objects or in-memory components. Tooling that auto-generates mocks lowers the cost of overusing them.
Why It Hurts
When tests mock everything, they assert on interactions — "method X was called once with these args" — which couples them to the implementation. Refactoring breaks them even when behavior is unchanged. More dangerously, heavily mocked tests can pass while the real system is broken, because the mocks encode the developer's assumptions about collaborators, not their actual behavior. Integration gaps go uncaught: each piece is tested against fakes, but the pieces never actually meet. The suite becomes a fragile echo of the code rather than a check on it.
Warning Signs
- Nearly every dependency in a test is a mock.
- Tests assert call counts and argument matchers more than results.
- Refactoring with no behavior change breaks many tests.
- Tests are green but the integrated system fails.
Better Alternatives
Use test doubles sparingly and at meaningful boundaries — external systems, slow or non-deterministic dependencies, side effects you cannot observe otherwise. Prefer sociable unit tests that exercise a unit together with its real lightweight collaborators, asserting on outcomes. Use real in-memory implementations (fakes) over strict mocks where practical. Cover service boundaries with contract tests so both sides agree on the real interface.
How to Refactor Out of It
Audit tests for mock density and interaction-only assertions. Replace mocks of simple or in-memory components with the real thing, and switch assertions from "was called" to "produced this result." Keep mocks for genuine external boundaries, and back them with contract tests that verify the boundary matches reality. Where a class needs many mocks, treat that as a design smell — too many dependencies — and consider splitting it. The result is tests that survive refactoring and actually catch integration defects.