A value object is immutable and has no individual identity: its content alone determines what it is. Two instances with matching content are interchangeable, so replacing one with a test double provides no benefit. section 2.2
Use these distinctions when deciding whether a dependency needs substitution:
- Treat immutable values such as the integer 5 and Product.Shampoo as ordinary inputs; their contents cannot change and their instances do not affect one another. section 2.2
- Replace mutable private dependencies when isolation requires controlling changing state, but leave private immutable dependencies real. section 2.2
- Represent functional decisions as values so tests compare outputs instead of configuring mocks or inspecting filesystem interactions. section 6.4
Turning FileUpdate into a value object
AuditManager returns a FileUpdate containing a file name and new content. Defining value equality lets the test assert one expected FileUpdate against the returned result, replacing two property assertions and avoiding reference-based comparison. section 6.4
Table 2.1. The differences between the London and classical schools of unit testing, summed up by the approach to isolation, the size of a unit, and the use of test doubles (view table figure)
| Isolation of |
A unit is |
Uses test doubles for |
|
|---|---|---|---|
| London school | Units | A class | All but immutable dependencies |
| Classical school | Unit tests | A class or a set of classes | Shared dependencies |
Use the dependency-isolation comparison to see why immutable dependencies remain real while mutable or shared dependencies may be replaced. section 2.2


