多くのファイルシステム操作を行うクラスがあり、実際のファイルシステムへのファイルの読み書きを心配せずにクラスをテストできるようにしたいとします。
public interface IFileSystem
{
bool FileExists(string filePath);
string[] ReadAllLines(string filePath);
//...more methods as appropriate
}
をし、ラッパークラスのインターフェイスを実装:
あなたは以下に似たインターフェースを作成、ファイルシステムの操作クラスで、その後
public class RealFileSystem : IFileSystem
{
public bool FileExists(string filePath)
{
return File.Exists(filePath);
}
public string[] ReadAllLines(string filePath)
{
return File.ReadAllLines(filePath);
}
}
を、あなたはそれをインスタンス化したいです依存性注入を使用して:
ご覧のとおり、上記のクラスには2つのコンストラクタがあります:1つはIFileSystemを実装するクラスのインスタンスを取り、もう1つはIFileSystemを実装します。 1つのクラスを呼び出さないクラスは、クラスの存続期間中に新しいRealFileSystem
をインスタンス化します。
次に、ユニットテストのために、そのクラスにIFileSystemのモックを注入できます。あなたはRhinoMocksまたは部品番号のようなモックフレームワークを使用することができ、またはあなたは自分自身をロールバックすることができます:
public class FakeFileSystem : IFileSystem
{
public bool FileExists(string filePath)
{
return true;
}
public string[] ReadAllLines(string filePath)
{
return new[] {"This", "is", "a", "bunch of", "text!"};
}
}
そして、あなたのテスト中に、実現する
var objectToTest = new ClassThatDoesFileSystemStuff(new FakeFileSystem());
重要なことは、あなたが緩くしているということですかあなたのクラスを結合する。 は、使用するIFileSystemのタイプを知るクラスではありません。 に、に、使用するIFileSystemの実装を教えてほしい。
+1良い例です!私の唯一の疑問は、2つのコンストラクタとの違いです.Poor Man's DIではなくDI Containerフレームワークを使用します。私はあなたがその例を複雑にしたくないと思っています。 – TrueWill
@TrueWill正解!私はいくつかのNinjectを愛しています:) –
@トルー私はいくつかの貧しい人のDIを愛しています。 :-) Ninjectは優れたDIコンテナの1つですが、本当に必要なのかどうか疑問に思うこともあります。 – bcarlso