A few months ago, the Spiderman (Market Intelligence) team needed to build a testing suite for one of our F# systems. I’m a fan of Inversion of Control (IoC) when it comes to testing, but I couldn’t find a lot of information on common conventions for this in F#. Since I was going through the trouble of pioneering this for my team, I documented my approach and created this step-by-step guide alongside some working code.
This has proven useful to us from a testing perspective and put us on the path of having code that is naturally compartmentalized. The important aspects of our code are now more readable and testable. This comes at the cost of an unfortunate “wire up” section that makes code a little harder to navigate, which you’ll see if you look at the guide above, but the benefits have outweighed this. Overall, we’re happy that we went this route because our code and tests are logically structured and nicely modularized.
I was recently reminded of our use of IoC because we’re about to kick off an initiative to profile our code to gain a deeper understanding of its individual components. Because we can test components individually, we have a lot of control there, but what’s even more exciting is that we can wire components together any way we want. We can use alternate versions of real implementations alongside highly-performant fakes, which will let us direct the pressure put on our system while still testing real-life functionality. We can isolate external dependencies the same way and pound them really hard, too. This is an exciting project for us because it’s going to give us a lot of information about where our system could shine if we invest in some weak links that are limiting other components’ potential.
I find myself far less concerned with issues around state and scope in F# than I am with imperative languages, so I’m not sold on using a full-scale Dependency Injection framework in F#. My experience with Inversion of Control in F#, however, is that it’s both a natural and useful fit.