Skip to main content

Seam

A point in the code where you can change behavior without editing the code at that point, usually by passing in something different.

A seam is a place you can plug in different behavior without touching the code around it. The term comes from Michael Feathers' Working Effectively with Legacy Code: most legacy code has none, which is exactly why it's hard to test.

A function that calls db.prepare(...) directly has no seam. There's nowhere to intervene: the function decides which database it talks to, and that decision is buried inside the function body. The only way to test it is to run it against a real database, every time, because nothing about how it reaches the database can be substituted from outside.

Pulling the database call behind a parameter creates one. A function that takes its dependency as an argument, instead of reaching out and grabbing it itself, lets the caller decide what that dependency actually is. In production, that's the real connection. In a test, it can be anything that answers to the same shape.

Finding a seam is usually the very first move in touching legacy code safely: not a rewrite, not a redesign, just noticing where a hardcoded dependency could become a parameter instead, and making exactly that one change.

Appears in