Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Needed: File system interfaces and implementation in .NET [duplicate]

Possible Duplicate:
How do you mock out the file system in C# for unit testing?

I write unit tests to my code, using Moq as a mocking framework.
My code includes calls to the file system, using direct calls to System.IO classes. For instance, File.Exists(...) etc.
I'd like to change that code to be more testable, so I should have an interface, say IFile, with a relevant method, say Exists(string path).
I know I can write it from scratch, but I thought that maybe there's a complete, robust framework that has both interfaces and implementations for the file system. This (desired) framework may also be some kind of a "service", and therefore its API doesn't have to be an "interface equivalent" to the System.IO namespace.
Note that I'd really like to have interfaces (and not static methods) so that my code is ready for dependency injection

What I got so far:

  • A somehow similar, yet not the same question was asked in stackoverflow
  • In codeplex.com there's a project named CodePlex Source Control Client (link) that has such classes in the source code (see /Source/TfsLibrary/Utility/ in the source code for specific details)

Any other recommendations?

like image 452
Ron Klein Avatar asked Mar 19 '09 22:03

Ron Klein


2 Answers

I've written adapters for the static System.IO.File and Directory methods. Then in my classes I do the following:

public class MyService {
  public IFile File {private get;set;}
  public MyService() {
    File = new FileImpl();
  }
  public void DoSomething() {
    File.ReadAllText("somefile");
  }
}

Then you can inject a mock as IFile for testing.

like image 139
Mauricio Scheffer Avatar answered Sep 20 '22 17:09

Mauricio Scheffer


Alright, I don't have the file-system-mock library you wish for (though it may be out there somewhere and would be cool), but this may help. One of the interesting concepts the "behaviorist" school of unit testing thought has come up with is the idea of an "outgoing interface". In some cases, there seems to be as much value in taking the calls an object makes to the entire universe of things outside of itself, and turning them into an interface, as there is in the typical act of making an interface for methods the outside world can call on your object).

In this case, you might consider, instead of mocking the entire file system, making one or more logically coherent interfaces for the answers and services your object needs from the outside world. The calls would merely answer the questions you need answered ... not dictate implementation. Then, you can use dependency injection as you mentioned to inject in the implementation you desire for your tests. And you'll probably use Moq to do so since you're familiar with it.

So, your "outgoing interface" might have a method called DoesFileExist(). It might accept a path. Or, if there is a "higher level" business question your object is trying to answer, and seeing if a file exists is merely the way that question is answered, then your outgoing interface might not have a method about file existence at all. It might instead be something like "DoIAppearToHaveAccessToTheFileServer", or even "IsThereAPreviouslySavedGame".

This is some work, but might be truer to the principles of good unit testing ... let your object-under-test express what it is trying to do, and let your unit tests test it and only it. Just a thought ... hope it helps.

like image 25
Charlie Flowers Avatar answered Sep 21 '22 17:09

Charlie Flowers