Code is hard to test when it reaches out for its dependencies. A classic checkout.php opens new PDO(...), reads $_POST, calls date() for a weekend discount, sends with mail() and echoes the page: no test can run it without a database, a mail server, a request and the right weekday. Each hidden dependency needs a seam, where a test can substitute its own object:
| Hidden dependency | Seam | What the test passes in |
|---|---|---|
| new PDO(...), SQL in the page | repository interface | fake or test database |
| mail(), cURL, Guzzle 23,452 | Mailer, PSR-18 client | mock or recording fake |
| time(), date(), new DateTime() | PSR-20 ClockInterface | frozen clock |
| $_GET, $_POST, echo, header() | handler taking an array, returning a response | plain arrays |
Pin the current behavior with characterization tests first, then extract a class that receives its dependencies, as Checkout does, and keep I/O at the edges.