When introducing the Composable Architecture last year we put a particular emphasis on side effects and testing. In fact, we devoted 8 entire episodes to those topics. This is because every architecture needs to have a story for side effects: it’s just a fact of life. But as soon as you introduce side effects you run the risk of destroying testability.
However, we were able to make side effects and testability live in harmony by employing an old technique that we talked about nearly two years ago: the environment. The environment provides a single place to put all of the things that can cause side effects, and we forbid ourselves from using any dependencies unless it is stored in the environment. This gives us a consistent way of accessing dependencies, and makes it trivial to swap out dependencies for controlled ones in tests, playgrounds, and we can even use mock dependencies when running the actual application if we wanted. This can be particularly useful if you don’t have internet or want to test your app in a very specific state.
However, the solution we gave is not the whole picture. It works well enough in many cases, but it has a few problems, and we can devise a much more robust and universal solution to the problem of dependencies in the Composable Architecture. In order to see this all we have to do is make a very small tweak to our reducer signature, and everything will naturally follow.
But before we get into that, let’s remind ourselves how we used the environment technique to control and test our side effects.