A seam is a place where pieces of code meet and a test can replace a dependency or behavior. It gives the test control over indirect inputs such as time, files, networks, random values, or logging. section 3.3.2 section 1.8
A dependency is the thing that makes behavior hard to control; a seam is the access point used to control it. Code with accessible seams is usually easier to test, read, and maintain as production behavior changes. section 3.3.2
Create seams by abstracting a dependency in forms that fit the code:
- Pass it as a parameter. section 4.2
- Use currying or a higher-order function. section 4.2
- Abstract a module dependency. section 4.2
- Inject an object or interface. section 4.2
Making a logger testable
A password verifier that imports a complicated logger directly is difficult to test with ordinary injection. Let the verifier receive a logger instead, then pass a fake logger whose info method records whether PASSED or FAIL was reported. The seam is the logger boundary, not the logging call itself. section 4.2
Seams improve test isolation: tests can receive consistent fake time, databases, networks, or machine settings rather than depend on their environment. This supports readable, maintainable tests whose results can be trusted. Missing seams are a common reason existing code is hard to test or safely refactor. section 12.0 section 1.8
Table 4.1 Techniques for injecting fakes (view table figure)
Compare parameter, functional, modular, and object-oriented techniques for creating a boundary where tests can inject fakes. section 4.2
