Once we’ve identified dependencies that make testing difficult, what do we do with them? We need to find ways to isolate them behind boundaries. Having isolated them, we can replace them with substitutes during testing.
In well-structured code, we can summarize our code as boxes of functionality. An arrow line from one box to another represents a dependency. With careful design, these boxes and arrows form a directed acyclic graph. By avoiding cycles, we make it easier to replace functionality. This brings benefits to ongoing maintenance that extend beyond testability.
We can implement boundaries using Swift protocols. With protocols in place, we can substitute different concrete types. But to even begin using a protocol, we need a place where we make the current type explicit. Once we spell out the type, we’ll be able to switch it to a protocol.
There are various techniques for making dependencies explicit. To illustrate them, let’s make another project for our experiments.