Q1:
You have three options here.
Option 1: Live with it.
(no example :P)
Option 2: Create a slight abstraction where required.
Instead of doing the file I/O (File.ReadAllBytes or whatever) in the method under test, you could change it so that the IO is done outside and a stream is passed instead.
public class MyClassThatOpensFiles
{
public bool IsDataValid(string filename)
{
var filebytes = File.ReadAllBytes(filename);
DoSomethingWithFile(fileBytes);
}
}
would become
// File IO is done outside prior to this call, so in the level
// above the caller would open a file and pass in the stream
public class MyClassThatNoLongerOpensFiles
{
public bool IsDataValid(Stream stream) // or byte[]
{
DoSomethingWithStreamInstead(stream); // can be a memorystream in tests
}
}
This approach is a tradeoff. Firstly, yes, it is more testable. However, it trades testability for a slight addition to complexity. This can hit maintainability and the amount of code you have to write, plus you may just move your testing problem up one level.
However, in my experience this is a nice, balanced approach as you can generalise and make testable the important logic without committing yourself to a fully wrapped file system. I.e. you can generalise the bits you really care about, while leaving the rest as is.
Option 3: Wrap the whole file system
Taking it a step further, mocking the filesystem can be a valid approach; it depends on how much bloat you're willing to live with.
I've gone this route 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 inject it everywhere and ultimately it was extra pain for little gain as many of the classes using it weren't hugely important to me. If I had been using an IoC container or writing something that was critical and the tests needed to be fast I might have stuck with it, though. As with all of these options, your mileage may vary.
As for your IoC container question:
Inject your test doubles manually. If you have to do a lot of repetitive work, just use setup/factory methods in your tests. Using an IoC container for testing would be overkill in the extreme! Maybe I am not understanding your second question, though.