Q1:
You have three options.
Option 1: live with it.
(no example: P)
Option 2: If necessary, create a small abstraction.
Instead of executing the I / O file (File.ReadAllBytes or something else) in the test method, you can change it so that IO runs outside and a stream is passed instead.
public class MyClassThatOpensFiles { public bool IsDataValid(string filename) { var filebytes = File.ReadAllBytes(filename); DoSomethingWithFile(fileBytes); } }
will become
This approach is a compromise. Firstly, yes, this is more verifiable. However, he trades in testability for a small addition to complexity. This can affect maintainability and the amount of code you have to write, plus you can simply move your test problem one level.
However, in my experience, this is a good balanced approach, since you can generalize and make important test logic without having to go over yourself with a fully packed file system. That is, you can generalize the bits that you are really interested in, leaving everything else as it is.
Option 3: Wrap the entire file system
Taking another step, mocking the file system may be a valid approach; it depends on how much swelling you are ready to live.
I went this way before; I had a wrapped file system implementation, but in the end I just deleted it. There were subtle differences in the API, I had to introduce them everywhere, and in the end it was an extra pain for a small gain, since many of the classes using it were not very important to me. If I used an IoC container or wrote something critical and the tests were supposed to be fast, I could be stuck with it. As with all of these options, your mileage may vary.
Regarding your question about the IoC container:
Enter test doubling manually. If you need to perform many repetitive actions, just use the / factory installation methods in your tests. Using an IoC container for testing would be overkill! Perhaps I do not understand your second question.