test-doubles-mocking · diff
git:20261005.042befb to git:20261005.625d3c1
17 added, 12 removed. Audit A to A.
---
name: test-doubles-mocking
description: Create test doubles with PHPUnit mocks for isolated unit testing in Symfony
capabilities: [read, search]
tags: [testing]
# projected by `bun run build` — do not edit by hand
allowed-tools:
- Read
- Glob
- Grep
---
# Test Doubles Mocking (Symfony)
## Use when
- - Building regression-safe behavior with TDD/functional/e2e tests.
- - Converting bug reports into executable failing tests.
+ - A class under test depends on a collaborator that is slow, external or non-deterministic, such as a payment gateway or a message bus.
+ - An interaction must be verified, such as `persist()` and `flush()` or a dispatched message.
+ - A repository needs an in-memory fake implementing its interface.
+ - Choosing between a dummy, stub, mock, spy or fake.
## Default workflow
- 1. Write failing test for target behavior and one boundary case.
- 2. Implement minimal code to pass.
- 3. Refactor while preserving green suite.
- 4. Broaden coverage for invalid/unauthorized/not-found paths.
+ 1. Pick the double by need: stub to feed values, mock to verify a call, fake for a working simplified implementation.
+ 2. Create it with `$this->createMock(Interface::class)` and stub with `->method('charge')->willReturn(...)`.
+ 3. Verify only when the interaction matters: `expects($this->once())->with(...)`, or `$this->callback()` to inspect a dispatched message.
+ 4. Script behavior with `willReturnOnConsecutiveCalls()`, `willThrowException()` or `willReturnCallback()`.
+ 5. For repositories, write an `InMemory` fake implementing the interface.
+ 6. Use `ProphecyTrait` with `prophesize()` and `reveal()` only if the project already relies on Prophecy.
## Guardrails
- - Prefer deterministic fixtures/builders.
- - Assert observable behavior, not internal implementation.
- - Keep tests isolated and stable in CI.
+ - Do not mock the class under test; a partial mock (`onlyMethods()`) is a last resort.
+ - Mock interfaces, not concrete classes.
+ - Prefer stubs over mocks, with one mock assertion per test.
+ - Do not over-mock: behavior that touches the database belongs in a functional test with the real repository.
## Progressive disclosure
- Use this file for execution posture and risk controls.
- Open references when deep implementation details are needed.
## Output contract
- - RED/GREEN/REFACTOR trace.
- - Test files changed and executed commands.
- - Coverage and confidence notes.
+ - The double type chosen for each collaborator, and why.
+ - Interactions verified, limited to those that matter.
+ - Fakes added under `tests/Fake`, if any.
## References
- `reference.md`