On many occasions I come accross code that is tightly coupled to the file system. Here is an example of an import functionality using a CSV file read out:
Class diagram:
On first glance the code looks okay but if you look closer it has some problems: * The Importer test is hard to maintain because we have to create and maintain a separate test file * The test takes longer because we need to access the disk which takes I/O resources. This adds up if you have thousands of unit tests. * The Importer violates the 'D' of the SOLID principle (Dependency Inversion Principle) because we are tightly coupled to System.IO.File class. # Improving the testability and design We can decouple the System.IO dependency by abstracting it away by leveraging a NuGet package called "System.IO.Abstractions". It's really useful for these use cases where you want to mock the file system:In our test we can then mock out the file system by specifying a test input file up front:This approach also works great for dealing with System.IO.Directory.Exists(), Create(), Delete() calls and many others. # Conclusion As maintainability is very important for code bases, we can raise it by introducing these kind of abstractions. It helps you to be less dependent on real implementations and in this case, as a side effect, it also speeds up the tests!