The technique of replacing protocols with simple data types goes far deeper than what we discuss above. Almost any protocol can be rewritten as a simple data type, and when you do so you can uncover a lot of interesting forms of composition that were previously hidden from us in the protocol world. To learn more watch our series of episodes on the “protocol witness” technique.
Well-designed dependencies and the Composable Architecture go hand-in-hand. If your dependencies are properly designed, then you will instantly unlock deep testing abilities of your application, including the ability to exhaustively assert the lifecycle of effects. To learn more watch our series of episodes on dependency management in the Composable Architecture.
There are tricks we can employ to better design our test dependencies so that we can exhaustively describe what dependencies a feature needs to do its job. This comes with tons of benefits for tests, but also strengthens our SwiftUI previews and can even be handy for production code.